package com.cloudkinto.service.fbaorderoutput.impl;

import cn.afterturn.easypoi.csv.entity.CsvExportParams;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.common.DicBusinessConstant;
import com.cloudkinto.common.DicBusinessItemConstant;
import com.cloudkinto.common.common.DateFormater;
import com.cloudkinto.common.common.DateUtils;
import com.cloudkinto.common.constant.GlobalConstants;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.error.ErrorEnum;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.exception.NotSufficientFundsException;
import com.cloudkinto.common.utils.*;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.extentity.stock.PickupStockRackDto;
import com.cloudkinto.extentity.stock.StockPickUpRackDto;
import com.cloudkinto.service.company.CompanyService;
import com.cloudkinto.service.dic.DicBusinessItemService;
import com.cloudkinto.service.dic.vo.DicItemRes;
import com.cloudkinto.service.fbaorderoutput.FbaOrderOutputService;
import com.cloudkinto.service.fbaorderoutput.vo.*;
import com.cloudkinto.service.file.FileService;
import com.cloudkinto.service.finance.CompanyAccountService;
import com.cloudkinto.service.finance.CostRecordService;
import com.cloudkinto.service.finance.vo.IdAndNameEntity;
import com.cloudkinto.service.operate.OperateRecordService;
import com.cloudkinto.service.operate.vo.OperateRes;
import com.cloudkinto.service.orderoutput.vo.*;
import com.cloudkinto.service.product.ProductOutService;
import com.cloudkinto.service.product.ProductStockFlowingService;
import com.cloudkinto.service.product.vo.flowing.ProductStockFlowingRes;
import com.cloudkinto.service.product.vo.rack.SendRes;
import com.cloudkinto.service.region.JpRegionService;
import com.cloudkinto.service.shipprice.ShipPriceService;
import com.cloudkinto.service.shop.ShopService;
import com.cloudkinto.service.stock.StockLogService;
import com.cloudkinto.service.stock.StockPickUpService;
import com.cloudkinto.service.stock.StockRecordService;
import com.cloudkinto.service.stock.vo.record.StockRecordPageRes;
import com.cloudkinto.service.storage.StorageService;
import com.cloudkinto.service.tailtrucks.TailTrucksService;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.BindException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author 张永远
 * @since 2020-06-04
 */
@Service
@Transactional(rollbackFor = Exception.class)//事务回滚
public class FbaOrderOutputServiceImpl extends ServiceImpl<FbaOrderOutputDao, FbaOrderOutputDo> implements FbaOrderOutputService {
    private static final String SHIPMENT_TYPE_0 = "SHIPMENT_TYPE_0";
    private static final String SHIPMENT_TYPE_1 = "SHIPMENT_TYPE_1";
    private static final String ORDER_OUTPUT_TYPE_2 = "FBA转运";
    private static final String ORDER_OUTPUT_TYPE_1 = "一件代发";
    @Autowired
    private FbaOrderOutputDao dao;
    @Autowired
    private ProductInfoDao productInfoDao;
    @Autowired
    private FbaOrderOutputPackageDao packageDao;
    @Autowired
    private FbaOrderOutputProductDao productDao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private StorageService storageService;
    @Autowired
    private JpRegionService regionService;
    @Autowired
    private ProductSkuMapDao productSkuMapDao;
    @Autowired
    private StorageDao storageDao;
    @Autowired
    private DicBusinessItemDao dicBusinessItemDao;
    @Autowired
    private DicBusinessItemService dicBusinessItemService;
    @Autowired
    private ShipPriceService mShipPriceService;
    @Autowired
    private StockRecordDao mStockRecordDao;
    @Autowired
    private StockRecordService stockRecordService;
    @Autowired
    private CompanyDao mCompanyDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private ShopService shopService;
    @Autowired
    private OperateRecordService operateRecordDao;
    @Autowired
    private StockLogService mStockLogService;
    @Autowired
    private CostRecordService mCostService;
    @Value("${gbc.template.filePath}")
    private String templatePath;
    @Autowired
    private FileService fileService;
    @Autowired
    private OrderRakutenShippingDao rakutenShippingDao;
    @Autowired
    private FbaStorageDao fbaStorageDao;
    @Autowired
    private FbaDimensDao fbaDimensDao;
    @Autowired
    private FbaShipPriceDao fbaShipPriceDao;
    @Autowired
    private CompanyDao companyDao;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private ThreadPoolTaskExecutor executor;
    @Autowired
    private TailTrucksDetailDao tailTrucksDetailDao;
    @Autowired
    private TailTrucksService tailTrucksService;
    @Autowired
    private OrderOutputDao outputDao;
    @Autowired
    private OrderOutputPackageDao outputPackageDao;
    @Autowired
    private OrderOutputProductDao outputProductDao;
    @Autowired
    private OrderInputDao orderInputDao;
    @Autowired
    private OrderInputProductDao orderInputProductDao;
    @Autowired
    private CompanyAccountService companyAccountService;
    @Autowired
    private ShippingAddressDao shippingAddressDao;
    @Autowired
    private ProductOutService productOutService;
    @Autowired
    private StockPickUpDao stockPickUpDao;
    @Autowired
    private ProductStockDao productStockDao;
    @Autowired
    private ProductStockRackDao productStockRackDao;
    @Autowired
    private StoragePositionDao storagePositionDao;
    @Autowired
    private StorageShelfDao storageShelfDao;
    @Autowired
    private ProductStockFlowingDao productStockFlowingDao;
    @Autowired
    private StockPickUpService stockPickUpService;
    @Autowired
    private StockPickUpDetailDao stockPickUpDetailDao;
    @Autowired
    private ProductStockFlowingService productStockFlowingService;
    @Autowired
    private ProductOutRecordDao productOutRecordDao;


    @Value("${gbc.uploadPath.filePathTemp}")
    private String filePathTemp;

    private int sizeArr[] = new int[]{5, 10, 20, 30, 40, 60, 80, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400};


    @Override
    public SingleResult addInit(Long currentUserId, Long companyId) {
        Map map = new HashMap();
        map.put("storageList", storageService.getList(new HashMap<>()));
        map.put("regionList", regionService.getList(new HashMap<>()));
        map.put("shopList", shopService.selectShopListInit(currentUserId, companyId));
        LambdaQueryWrapper<DicBusinessItemDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.fbaOrderOutPutTruck);
        List<DicBusinessItemDo> trackCompanyList = dicBusinessItemDao.selectList(wrapper);
        List<IdAndNameEntity> trackList = new ArrayList<>();
        for (DicBusinessItemDo itemDo : trackCompanyList) {
            trackList.add(new IdAndNameEntity(itemDo.getId().intValue(), itemDo.getDicItemValue()));
        }

        //fbaStorage
        QueryWrapper wrapper1 = new QueryWrapper();
        wrapper1.orderByAsc("fba_code");
        List<FbaStorageDo> fbaStorageDos = fbaStorageDao.selectList(wrapper1);
        List<Map> fbaStorageList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(fbaStorageDos)) {
            fbaStorageDos.forEach(fbaStorageDo -> {
                Map fbaMap = new HashMap();
                fbaMap.put("id", fbaStorageDo.getId());
                fbaMap.put("code", fbaStorageDo.getFbaCode());
                fbaMap.put("name", fbaStorageDo.getFbaName());
                fbaMap.put("address", fbaStorageDo.getAddress());
                fbaMap.put("postCode", fbaStorageDo.getPostCode());
                fbaMap.put("tel", fbaStorageDo.getTelPhone());
                fbaStorageList.add(fbaMap);
            });
        }
        map.put("fbaStorageList", fbaStorageList);

        List<ShippingAddressDo> addressList;
        if (companyId == null) {
            addressList = shippingAddressDao.selectList(new QueryWrapper<ShippingAddressDo>());
        } else {
            addressList = shippingAddressDao.selectList(new QueryWrapper<ShippingAddressDo>().eq("company_id", companyId));
        }
        List<Map> resList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(addressList)) {
            addressList.forEach(addressDo -> {
                Map map1 = new HashMap();
                map1.put("id", addressDo.getId());
                map1.put("name", addressDo.getContact());
                map1.put("companyName", addressDo.getCompanyName());
                map1.put("address", addressDo.getAddress());
                map1.put("postCode", addressDo.getPostCode());
                map1.put("tel", addressDo.getTelPhone());
                resList.add(map1);
            });
        }
        map.put("ownAddressList", resList);

        map.put("trackList", trackList);

        List<Map> productTypeList = new ArrayList<>();
        LambdaQueryWrapper<DicBusinessItemDo> wrapperProductType = new LambdaQueryWrapper<>();
        wrapperProductType.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.productType);
        List<DicBusinessItemDo> businessItemDoList = dicBusinessItemDao.selectList(wrapperProductType);
        if (!CollectionUtils.isEmpty(businessItemDoList)) {
            for (DicBusinessItemDo businessItemDo : businessItemDoList) {
                Map mapProductType = new HashMap();
                mapProductType.put("id", businessItemDo.getId());
                mapProductType.put("value", businessItemDo.getDicItemValue());
                productTypeList.add(mapProductType);
            }
        }
        map.put("productTypeList", productTypeList);
        map.put("companyTree", companyService.tree());
        return SingleResult.success(map);
    }

    @Override
    public String fbaStorageAdd(FbaOrderOutputAddReq req, Long userId) {
        addCheck(req);
        FbaOrderOutputDo entityDo = new FbaOrderOutputDo();
        if (req.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
            FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(req.getFbaStorageId());
            if (StringUtils.isBlank(req.getAddress())) {
                req.setAddress(fbaStorageDo.getAddress());
            }
            if (StringUtils.isBlank(req.getPostCode())) {
                req.setPostCode(fbaStorageDo.getPostCode());
            }
            if (StringUtils.isBlank(req.getReceiverName())) {
                req.setReceiverName(fbaStorageDo.getFbaName());
            }
            if (StringUtils.isBlank(req.getTelPhone())) {
                req.setTelPhone(fbaStorageDo.getTelPhone());
            }
        } else {
            ShippingAddressDo fbaStorageDo = shippingAddressDao.selectById(req.getFbaStorageId());
            if (StringUtils.isBlank(req.getAddress())) {
                req.setAddress(fbaStorageDo.getAddress());
            }
            if (StringUtils.isBlank(req.getPostCode())) {
                req.setPostCode(fbaStorageDo.getPostCode());
            }
            if (StringUtils.isBlank(req.getReceiverName())) {
                req.setReceiverName(fbaStorageDo.getCompanyName());
            }
            if (StringUtils.isBlank(req.getTelPhone())) {
                req.setTelPhone(fbaStorageDo.getTelPhone());
            }
        }
        BeanUtils.copyProperties(req, entityDo);
        entityDo.setOrderNo(req.getOrderNo());
//        if (StringUtils.isEmpty(req.getArea())) {
//            JpRegionDo regionDo = regionService.getRegionDoByPostCode(req.getPostCode());
//            if (regionDo != null)
//                entityDo.setArea(regionDo.getName());
//        }
        if (StringUtils.isNotBlank(req.getDeliveryDate()))
            entityDo.setDeliveryDate(TimeUtils.parseDate(req.getDeliveryDate()));
        handlerAddBefore(entityDo, userId);
        entityDo.setStorageType(req.getStorageType());
        dao.insert(entityDo);
        handlerFbaStorageAdd(entityDo, req, userId);

        entityDo.setFbaOrderOutputNumber(OrderCodeUtil.getFbaOrderOutputNumber(entityDo.getId()));
        entityDo.setTrackId(req.getTrackId());
        dao.updateById(entityDo);
        //日志操作
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_CREATE_FBA, entityDo.getId(), userId, 6);

        fileService.uploadFile(req.getFileId());
        fileService.uploadFile(req.getProductFileId());
        fileService.uploadFile(req.getOtherFileId());
        fileService.uploadFile(req.getSignatureFileId());
        LambdaQueryWrapper<OrderInputDo> orderInputWrapper = new LambdaQueryWrapper<>();
        orderInputWrapper.eq(OrderInputDo::getOrderInputNumber, entityDo.getOrderInputNumber());
        OrderInputDo orderInputDo = orderInputDao.selectOne(orderInputWrapper);
        if (orderInputDo != null) {
            orderInputDo.setStatus(DicBusinessItemConstant.inPutTurnFba);
            orderInputDo.setUpdateBy(userId);
            orderInputDo.setUpdateTime(new Date());
            operateRecordDao.operateAddRecord(SysConstant.OPERATE_TURN_FBA_ORDER, orderInputDo.getId(), userId, 2);
        }
        if (entityDo.getTrackId() < DicBusinessItemConstant.fbaTrackName2t) return null;
//        threadPoolTaskExecutor.execute(() -> {
//            TailTrucksJointFbaReq req1 = new TailTrucksJointFbaReq();
//            List<Long> fbaOrderIds = new ArrayList<>();
//            fbaOrderIds.add(entityDo.getId());
//            req1.setIds(fbaOrderIds);
//            tailTrunkService.jointFbaTrucks(req1, userId);
//        });
        return null;
    }

    @Override
    public SingleResult setCost(Long id, double fee, Long userId) {
        FbaOrderOutputDo orderOutputDo = dao.selectById(id);
        orderOutputDo.setOperateFee(fee);
        orderOutputDo.setTaxFee((orderOutputDo.getShipFee() + orderOutputDo.getOutFee() + fee) * 0.1);
        orderOutputDo.setUpdateBy(userId);
        orderOutputDo.setUpdateTime(new Date());
        orderOutputDo.setIsSetFee(SysConstant.DELETE_FLAG_TRUE);

        dao.updateById(orderOutputDo);
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_UPDATE_FBA_LABEL_FEE, id, userId, 6);

//        operateRecord("修改标签费", id, userId);
        if (orderOutputDo.getStatus() >= DicBusinessItemConstant.fbaOrderSendOutStatus) {
            return SingleResult.failure("改订单已出库扣费，修改无效");
        }
        return SingleResult.success();
    }

    @Override
    public List<Map> computationalCosts(FbaOrderOutputComputationalCostsReq req, Long companyId) {
        if (req.getFbaStorageId() == null && StringUtils.isBlank(req.getPostCode())) {
            return null;
        }
        List<Map> priceList = new ArrayList<>();
        if (companyId == null) {
            ShopDo shopDo = shopService.getById(req.getShopId());
            if (shopDo != null) companyId = shopDo.getCompanyId();
        }
        LambdaQueryWrapper<DicBusinessItemDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.fbaOrderOutPutTruck);
        List<DicBusinessItemDo> businessItemDoList = dicBusinessItemDao.selectList(wrapper);
        for (int i = 0; i < businessItemDoList.size(); i++) {
            handlerFee(req, businessItemDoList.get(i), companyId, priceList, i);
        }
        return priceList;
    }

    private void handlerFee(FbaOrderOutputComputationalCostsReq req, DicBusinessItemDo businessItemDo, Long companyId, List<Map> priceList, int index) {
        double totalPriceBySize = 0;
        double totalPriceByVolume = 0;

        //计算总体积 总尺寸
        double maxSize = 0;//包裹最大尺寸
        double maxWeight = 0; //包裹最大重量
        double totalVolume = req.getPackageAddReqList().stream().mapToDouble(packageAddReq -> {
            return packageAddReq.getHeight() * packageAddReq.getWidth() * packageAddReq.getLength() / 1000000 * packageAddReq.getPackageCount();
        }).sum();
        //        double totalVolumeAndWeight = 0;
        double totalWeight = req.getPackageAddReqList().stream().mapToDouble(packageAddReq -> {
            return packageAddReq.getWeight() * packageAddReq.getPackageCount();
        }).sum();
        //如果flag为true表示 有的包裹价格匹配不上，则 不展示该快递公司的 运算价格
        boolean sizeFlag = false;
        boolean volumeFlag = false;

        CompanyDo companyDo = companyDao.selectById(companyId);
        Long fbaStorageId = getFbaStorageId(req.getFbaStorageId(), req.getStorageId(), req.getPostCode());
        FbaShipPriceRes sizePriceRes = new FbaShipPriceRes();
        for (FbaOrderOutputPackageAddReq packageAddReq : req.getPackageAddReqList()) {
            double size = packageAddReq.getHeight() + packageAddReq.getWidth() + packageAddReq.getLength();
            double volume = packageAddReq.getHeight() * packageAddReq.getWidth() * packageAddReq.getLength() / 1000000;
            double weight = packageAddReq.getWeight();

            maxSize = Math.max(size, maxSize);
            maxWeight = Math.max(weight, maxWeight);
            //根据三边和计算
            sizePriceRes = getShipPriceWithReason(size, weight, 1, req.getStorageId(), businessItemDo.getId(), fbaStorageId, companyDo.getShipPriceVersion());
            if (sizePriceRes.getPriceDo() != null) {
                totalPriceBySize += sizePriceRes.getPriceDo().getPrice() * packageAddReq.getPackageCount();
            } else {
                sizeFlag = true;
                break;
            }
        }

        //根据体积计算  sizeType 2
        FbaShipPriceRes volPriceRes = getShipPriceWithReason(totalVolume, totalWeight, 2, req.getStorageId(), businessItemDo.getId(), fbaStorageId, companyDo.getShipPriceVersion());
        if (volPriceRes.getPriceDo() != null) {
            totalPriceByVolume = volPriceRes.getPriceDo().getPrice();
        } else {
            volumeFlag = true;
        }

        int packageCounts = req.getPackageAddReqList().stream().mapToInt(FbaOrderOutputPackageAddReq::getPackageCount).sum();

        //加急快递（一件代发 佐川即便）
        if (index == 0 && maxSize <= 260) {
            List<DicItemRes> dicItemList = dicBusinessItemService.getDicItemList(DicBusinessConstant.trackCompany);
            DicItemRes cheapRes = null;
            double costPrice = 0;//成本
            double cheapPrice = 0;//报价
            track:
            for (DicItemRes dicItemRes : dicItemList) {
                if (!(dicItemRes.getId().equals(StaticDict.Track_Type.SagawaExpress.getValue()) || dicItemRes.getId().equals(StaticDict.Track_Type.YamatoExpress.getValue()))) {
                    continue track;
                }
                double oneTrackPrice = 0;//报价
                double oneTrackCost = 0;//成本
                for (FbaOrderOutputPackageAddReq packageAddReq : req.getPackageAddReqList()) {
                    double size = packageAddReq.getHeight() + packageAddReq.getWidth() + packageAddReq.getLength();
                    double weight = packageAddReq.getWeight();

                    double[] packageSize = mShipPriceService.getSizeOrderDesc(packageAddReq.getLength(), packageAddReq.getWidth(), packageAddReq.getHeight());

                    ShipPriceDo shipPrices = mShipPriceService.queryByRegionAndSize(regionService.getStateIdByRegionId(fbaStorageDao.selectById(fbaStorageId).getReginJpId()), weight, size, packageSize[0], packageSize[1], packageSize[2], 0, 0, req.getStorageId(), dicItemRes.getId(), companyDo.getShipPriceVersion());
                    if (shipPrices == null || shipPrices.getOriginalPrice() == null || shipPrices.getOriginalPrice() == 0) {
                        //未找到费用信息或 成本
//                        sizeFlag = true;
                        continue track;
                    } else {
                        oneTrackCost += shipPrices.getOriginalPrice() * packageAddReq.getPackageCount();
                        oneTrackPrice += shipPrices.getPrice() * packageAddReq.getPackageCount();
                    }
                }
                if (cheapRes == null || costPrice > oneTrackCost) {
                    cheapRes = dicItemRes;
                    cheapPrice = oneTrackPrice;
                    costPrice = oneTrackCost;
                }
            }
            if (cheapRes != null) {
                Map<String, Object> sagawaMap = new HashMap<>();
                sagawaMap.put("shipFee", cheapPrice);
                sagawaMap.put("operateFee", packageCounts * 200 * 0.5);
                sagawaMap.put("trackId", cheapRes.getId());
                sagawaMap.put("trackName", StaticDict.Track_Type.getText(cheapRes.getParentId()));
                sagawaMap.put("type", "次日发出");
                sagawaMap.put("size", maxSize + "cm / 260cm");
                sagawaMap.put("flag", true); //如果是true 则可以选择
                priceList.add(sagawaMap);
            }
        } else if (index == 0 && maxSize > 260) {
            Map<String, Object> sagawaMap = new HashMap<>();
            sagawaMap.put("trackId", DicBusinessItemConstant.sagawaExpress);
            sagawaMap.put("trackName", StaticDict.Track_Type.getText(DicBusinessItemConstant.sagawaExpress));
            sagawaMap.put("type", "包裹最大尺寸：" + maxSize + "cm 超过支持的最大尺寸(260cm)");
            sagawaMap.put("size", maxSize + "cm / 260cm");
            sagawaMap.put("flag", false); //如果是true 则可以选择
            priceList.add(sagawaMap);
        }

        //根据尺寸计算得出结果
        if (!sizeFlag) {
            Map sizeMap = new HashMap();
            sizeMap.put("shipFee", totalPriceBySize);
            sizeMap.put("operateFee", packageCounts * 100);
            sizeMap.put("trackId", businessItemDo.getId());
            sizeMap.put("trackName", businessItemDo.getDicItemValue());
            if (req.getFbaStorageId() == null || req.getFbaStorageId() == 34 || req.getFbaStorageId() == 35 || (req.getFbaStorageId() >= 80 && req.getFbaStorageId() <= 86)) {
                sizeMap.put("type", "不支持乐天和私人地址");
                sizeMap.put("flag", false); //如果是true 则可以选择
            } else {
                sizeMap.put("type", "3日内发出");
                sizeMap.put("flag", true); //如果是true 则可以选择

            }
            sizeMap.put("size", maxSize + "cm / " + sizePriceRes.getSizeOrVol() + "cm");
            priceList.add(sizeMap);
        }
        //根据体积计算得出结果
        else if (!volumeFlag) {
            Map<String, Object> volumeMap = new HashMap<>();
            volumeMap.put("shipFee", totalPriceByVolume);
            volumeMap.put("operateFee", totalVolume * 280);
            volumeMap.put("trackId", businessItemDo.getId());
            volumeMap.put("trackName", businessItemDo.getDicItemValue());
            if (businessItemDo.getId().equals(DicBusinessItemConstant.fbaTrackNameXinong)) {
                volumeMap.put("type", "3日内发出");
                volumeMap.put("size", numberfromat(totalVolume) + "m³ /" + numberfromat(volPriceRes.getSizeOrVol()) + " m³");
                volumeMap.put("flag", true);
            } else if (businessItemDo.getId().equals(DicBusinessItemConstant.fbaTrackName2t) && req.getFbaStorageId() != null && ((req.getFbaStorageId() >= 16 && req.getFbaStorageId() <= 19) || req.getFbaStorageId() == 33 || req.getFbaStorageId() == 42 || req.getFbaStorageId() == 56 || req.getFbaStorageId() == 70)) {
                volumeMap.put("type", "无法派送");
                volumeMap.put("flag", false);
            } else {
                volumeMap.put("size", numberfromat(totalVolume) + "m³ /" + numberfromat(volPriceRes.getSizeOrVol()) + " m³");
                volumeMap.put("type", String.format("预计%s号送达(节假日顺延)", TimeUtils.getddDate(4)));
                volumeMap.put("flag", true);
            }
            priceList.add(volumeMap);
        } else if (StringUtils.isNotBlank(sizePriceRes.getReason()) || StringUtils.isNotBlank(volPriceRes.getReason())) {
            //不满足条件
            Map<String, Object> volumeMap = new HashMap<>();
            volumeMap.put("trackId", businessItemDo.getId());
            volumeMap.put("trackName", businessItemDo.getDicItemValue());

            volumeMap.put("type", StringUtils.isNotBlank(volPriceRes.getReason()) ? volPriceRes.getReason() : sizePriceRes.getReason());
            if (StringUtils.isNotBlank(volPriceRes.getReason())) {//体积或重量
                if ("weightReason".equals(volPriceRes.getType())) {
                    //重量原因
                    volumeMap.put("size", numberfromat(maxWeight) + "kg /" + numberfromat(volPriceRes.getSizeOrVol()) + " kg");
                } else {
                    volumeMap.put("size", numberfromat(totalVolume) + "m³ /" + numberfromat(volPriceRes.getSizeOrVol()) + " m³");
                }
            } else {
                if ("weightReason".equals(sizePriceRes.getType())) {//三遍和或重量
                    //重量原因
                    volumeMap.put("size", numberfromat(maxWeight) + "kg /" + numberfromat(sizePriceRes.getSizeOrVol()) + " kg");
                } else {
                    volumeMap.put("size", maxSize + "cm / " + sizePriceRes.getSizeOrVol() + "cm");
                }
            }
            volumeMap.put("flag", false);
            priceList.add(volumeMap);
        }
    }

    private double getVolumeAndWeight(double volume, double weight) {
        double volumeAndWeight = volume * 280 - weight > 0 ? volume * 280 : weight;
        for (int i = 0; i < sizeArr.length; i++) {
            if (volumeAndWeight < sizeArr[i]) return sizeArr[i];
        }
        return volumeAndWeight;
    }

    private double numberfromat(double totalVolume) {
        return new BigDecimal(totalVolume).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }


    private void handlerFee(FbaOrderOutputDo entityDo, Long trackId) {
        if (trackId == null) trackId = entityDo.getTrackId();
        entityDo.setTrackId(trackId);
        LambdaQueryWrapper<FbaOrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, entityDo.getId());
        List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
        final int[] productCounts = {0};//如果是按三边和计算，每个商品200,统计所有商品的总数量
        double totalPriceBySize = 0, totalOriginPriceBySize = 0;
        double totalPriceBySizeSagawa = 0, totalOriginPriceBySizeSagawa = 0;
        double totalPriceByVolume = 0, totalOriginPriceByVolume = 0;
        //计算总体积 总尺寸
        double totalSize = 0;
        double totalVolume = 0;
        double totalVolumeAndWeight = 0;
        double totalWeight = 0;
        //如果flag为true表示 有的包裹价格匹配不上，则 不展示该快递公司的 运算价格
        boolean sizeFlag = false;
        boolean volumeFlag = false;
        CompanyDo companyDo = companyDao.selectById(entityDo.getCompanyId());

        Long fbaStorageId = getFbaStorageId(entityDo.getFbaStorageId(), entityDo.getStorageId(), entityDo.getPostCode());
        for (FbaOrderOutputPackageDo packageDo : packageDoList) {
            double size = packageDo.getHeight() + packageDo.getWidth() + packageDo.getLength();
            double volume = packageDo.getHeight() * packageDo.getWidth() * packageDo.getLength() / 1000000;
            double weight = packageDo.getWeight();
            double[] packageSize = mShipPriceService.getSizeOrderDesc(packageDo.getLength(), packageDo.getWidth(), packageDo.getHeight());

            totalSize += size;
            totalVolume += volume * packageDo.getCount();
            totalVolumeAndWeight += getVolumeAndWeight(volume, weight) * packageDo.getCount();
            totalWeight += weight * packageDo.getCount();

            //根据三边和计算
            FbaShipPriceDo shipPriceDo = getShipPrice(size, weight, 1, entityDo.getStorageId(), entityDo.getTrackId(), fbaStorageId, companyDo.getShipPriceVersion());
            if (shipPriceDo != null) {
                totalPriceBySize += shipPriceDo.getPrice() * packageDo.getCount();
                totalOriginPriceBySize += shipPriceDo.getOriginalPrice() * packageDo.getCount();
            } else {
                sizeFlag = true;
            }
            ShipPriceDo shipPrices = mShipPriceService.queryByRegionAndSize(regionService.getStateIdByRegionId(fbaStorageDao.selectById(fbaStorageId).getReginJpId()), weight, size, packageSize[0], packageSize[1], packageSize[2], 0, 0, entityDo.getStorageId(), DicBusinessItemConstant.sagawaExpress, companyDo.getShipPriceVersion());
            if (shipPrices == null) {
                //未找到费用信息，请人工处理
                sizeFlag = true;
            } else {
                totalPriceBySizeSagawa += shipPrices.getPrice() * packageDo.getCount();
                totalOriginPriceBySizeSagawa += shipPrices.getOriginalPrice() * packageDo.getCount();
            }
        }

        //根据体积计算  sizeType 2
        FbaShipPriceDo shipPriceDo = getShipPrice(totalVolume, totalWeight, 2, entityDo.getStorageId(), entityDo.getTrackId(), fbaStorageId, companyDo.getShipPriceVersion());
        if (shipPriceDo != null) {
            totalPriceByVolume = shipPriceDo.getPrice();
            totalOriginPriceByVolume = shipPriceDo.getOriginalPrice();
        } else {
            volumeFlag = true;
        }

        int packageCounts = packageDoList.stream().mapToInt(FbaOrderOutputPackageDo::getCount).sum();
        packageDoList.stream().forEach(fbaOrderOutputPackageDo -> {
            //统计商品数量计算操作费
            LambdaQueryWrapper<FbaOrderOutputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDoLambdaQueryWrapper.eq(FbaOrderOutputProductDo::getPackageId, fbaOrderOutputPackageDo.getId());
            List<FbaOrderOutputProductDo> orderOutputProductDoList = productDao.selectList(productDoLambdaQueryWrapper);
            if (!CollectionUtils.isEmpty(orderOutputProductDoList)) {
                productCounts[0] += orderOutputProductDoList.stream().mapToInt(FbaOrderOutputProductDo::getCount).sum() * fbaOrderOutputPackageDo.getCount();
            }
        });

        //加急快递
        if (DicBusinessItemConstant.sagawaExpress.equals(trackId) || DicBusinessItemConstant.yamatoExpress.equals(trackId)) {
            entityDo.setShipFee(totalPriceBySizeSagawa);
            entityDo.setOriginShipFee(totalOriginPriceBySizeSagawa);
            entityDo.setOutFee(packageCounts * 200 * 0.5);
        }
        //根据尺寸计算得出结果
        if (DicBusinessItemConstant.fbaTrackNameGreenBox.equals(trackId)) {
            entityDo.setShipFee(totalPriceBySize);
            entityDo.setOriginShipFee(totalOriginPriceBySize);
            entityDo.setOutFee(packageCounts * 200 * 0.5);
        } else if (totalPriceByVolume != 0) {//根据体积计算得出结果
            entityDo.setShipFee(totalPriceByVolume);
            entityDo.setOriginShipFee(totalOriginPriceByVolume);
            entityDo.setOutFee(280 * totalVolume);
        }
        if (entityDo.getIsSetFee() == SysConstant.DELETE_FLAG_FALSE) {
            entityDo.setOperateFee(getPackageLabelFee(packageCounts, companyDo));
            if (entityDo.getProductFileId() != null) {
                entityDo.setOperateFee(entityDo.getOperateFee() + getProductLabelFee(productCounts[0], companyDo, entityDo));
            }
        }

        //计算taxFee
        double taxFee = (entityDo.getOperateFee() + entityDo.getShipFee() + entityDo.getOutFee()) * 0.1;
        entityDo.setTaxFee(taxFee);

        entityDo.setTrackId(trackId);
//        dao.updateById(entityDo);
    }

    private double getPackageLabelFee(int packageCounts, CompanyDo companyDo) {
        //普价客户且数量大于100时按80算
        if (packageCounts >= 100 && companyDo.getPackageLabel().intValue() == 100) {
            return packageCounts * 80;
        } else {
            return packageCounts * companyDo.getPackageLabel();
        }
    }

    private double getProductLabelFee(int productCounts, CompanyDo companyDo, FbaOrderOutputDo entityDo) {
        //普价客户且数量大于500时按60算
        if (productCounts >= 500 && companyDo.getProductLabel().intValue() == 80) {
            return productCounts * 60;
        } else if (productCounts > 0) {
            return productCounts * companyDo.getProductLabel();
        } else {
            entityDo.setTips(entityDo.getTips() + "sys:无产品数量,按100个计算");
            return 100 * companyDo.getProductLabel();
        }
    }

    private void handlerFbaStorageAdd(FbaOrderOutputDo entityDo, FbaOrderOutputAddReq req, Long userId) {
        if (!CollectionUtils.isEmpty(req.getPackageList())) {
            StringBuilder sb = new StringBuilder();
            for (FbaOrderOutputPackageAddReq packageAddReq : req.getPackageList()) {
                FbaOrderOutputPackageDo packageDo = new FbaOrderOutputPackageDo();
                BeanUtils.copyProperties(packageAddReq, packageDo);
                packageDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                packageDo.setCreateBy(userId);
                packageDo.setCreateTime(new Date());
                packageDo.setFbaOrderOutputId(entityDo.getId());
                if (!sb.toString().contains(packageAddReq.getPoNumber())) {
                    if (sb.length() > 0) {
                        sb.append(",");
                    }
                    sb.append(packageAddReq.getPoNumber());
                }
                if (packageAddReq.getHeight() < 0) throw new BizException(SysConstant.FbaOrder_Check_Package_Height);
                packageDo.setHeight(packageAddReq.getHeight());
                if (packageAddReq.getLength() < 0) throw new BizException(SysConstant.FbaOrder_Check_Package_Length);
                packageDo.setLength(packageAddReq.getLength());
                if (packageAddReq.getWeight() < 0) throw new BizException(SysConstant.FbaOrder_Check_Package_Weight);
                packageDo.setWeight(packageAddReq.getWeight());
                if (packageAddReq.getWidth() < 0) throw new BizException(SysConstant.FbaOrder_Check_Package_Width);
                packageDo.setWidth(packageAddReq.getWidth());
                if (packageAddReq.getPackageCount() < 0)
                    throw new BizException(SysConstant.FbaOrder_Check_Package_Count);
                packageDo.setCount(packageAddReq.getPackageCount());
                packageDao.insert(packageDo);

                if (!CollectionUtils.isEmpty(packageAddReq.getProductList())) {
                    for (FbaOrderOutputProductAddReq productAddReq : packageAddReq.getProductList()) {
                        ProductInfoDo productInfoDo = productInfoDao.selectById(productAddReq.getProductId());
                        if (productInfoDo == null) throw new BizException(SysConstant.Product_NotExist);
                        FbaOrderOutputProductDo outputProductDo = new FbaOrderOutputProductDo();
                        BeanUtils.copyProperties(productAddReq, outputProductDo);
                        outputProductDo.setCount(productAddReq.getCount());
                        if (productAddReq.getCount() < 0) throw new BizException(SysConstant.FbaOrder_Check_Sku_Count);
                        outputProductDo.setCreateTime(new Date());
                        outputProductDo.setCreateBy(userId);
                        outputProductDo.setOrderId(entityDo.getId());
                        outputProductDo.setPackageId(packageDo.getId());
                        outputProductDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                        outputProductDo.setProductId(productAddReq.getProductId());
//                        if (entityDo.getTrackId() == DicBusinessItemConstant.fbaTrackName2t ||
//                                entityDo.getTrackId() == DicBusinessItemConstant.fbaTrackName4t ||
//                                entityDo.getTrackId() == DicBusinessItemConstant.fbaTrackName10t) {
//                            // 吨车出库不验证库存数量
//                        } else {
                        verifyStock(entityDo.getShopId(), entityDo.getStorageId(), outputProductDo.getProductId(), packageAddReq.getPackageCount() * outputProductDo.getCount(), productInfoDo.getCommoditySku());
//                        }
                        productDao.insert(outputProductDo);
                    }
                }
            }
            entityDo.setPoNumber(sb.toString());
            updateFBATrackId(entityDo);
        }
    }


    private void handlerAddProduct(List<OrderOutputProductAddReq> orderProductList, FbaOrderOutputDo entityDo, Long userId) {
        FbaOrderOutputPackageDo packageDo = new FbaOrderOutputPackageDo();
        packageDo.setCreateBy(userId);
        packageDo.setFbaOrderOutputId(entityDo.getId());
        packageDo.setCreateTime(new Date());
        packageDao.insert(packageDo);
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder stringBuilder2 = new StringBuilder();
        for (OrderOutputProductAddReq productReq : orderProductList) {
            if (productReq.getProductId() == 0)
                throw new BizException(SysConstant.FbaOrder_Check_Sku_NotExist, productReq.getCommoditySku());
            ProductInfoDo productInfoDo = productInfoDao.selectById(productReq.getProductId());
            if (productInfoDo == null)
                throw new BizException(SysConstant.FbaOrder_Check_Sku_NotExist, productReq.getCommoditySku());
            FbaOrderOutputProductDo outputProductDo = new FbaOrderOutputProductDo();
            outputProductDo.setProductId(productReq.getProductId());

            outputProductDo.setCount(productReq.getCount());
            outputProductDo.setPackageId(packageDo.getId());
            outputProductDo.setOrderId(packageDo.getFbaOrderOutputId());
            outputProductDo.setCreateBy(userId);
            outputProductDo.setCreateTime(new Date());
            outputProductDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
            String productSku = "";
            ProductInfoDo productInfo = productInfoDao.selectById(outputProductDo.getProductId());
            if (productInfo != null) {
                productSku = productInfoDo.getCommoditySku();
            }
            verifyStock(entityDo.getShopId(), entityDo.getStorageId(), outputProductDo.getProductId(), outputProductDo.getCount(), productSku);
            productDao.insert(outputProductDo);
            if (stringBuilder.length() < 100) {
                if (stringBuilder.length() > 0) stringBuilder.append(",");
                stringBuilder.append(productSku);
            }
            if (stringBuilder2.length() < 100) {
                if (stringBuilder2.length() > 0) stringBuilder2.append(",");
                stringBuilder2.append(productInfo.getStorageSku());
            }
        }
        // 产品数量过多时需要人工审核，状态改为-1
        if (orderProductList.size() > SysConstant.OUTPUT_PRODUCT_SIZE_LIMIT) {
            entityDo.setStatus(DicBusinessItemConstant.fbaInCreateState);
        }
        entityDo.setCommoditySku(stringBuilder.toString());
        entityDo.setStorageSku(stringBuilder2.toString());
        updateById(entityDo);
    }

    /**
     * 验证库存
     *
     * @param shopId
     * @param storageId
     * @param productId
     * @param count
     * @param commoditySku
     */
    private void verifyStock(Long shopId, Long storageId, Long productId, int count, String commoditySku) {
        LambdaQueryWrapper<StockRecordDo> wrapper = new LambdaQueryWrapper();
//            sendOutEntity.getCommoditySku(), sendOutEntity.getShopId(), sendOutEntity.getStorageId()
        wrapper.eq(StockRecordDo::getShopId, shopId).eq(StockRecordDo::getStorageId, storageId).eq(StockRecordDo::getProductInfoId, productId);
        StockRecordDo recordBean = mStockRecordDao.selectOne(wrapper);
        if (shopId == null) shopId = 0L;
        int inputCount = orderInputProductDao.selectInputOrderSkuCount(productId, shopId, storageId, DicBusinessItemConstant.inPutStorage);
        int waitCount = mStockRecordDao.getOrderOutCount(productId, shopId, storageId) + mStockRecordDao.getOrderOutTurn2FbaCount(productId, shopId, storageId);
        int canUseCount = 0;
        if (recordBean == null) {
            canUseCount = inputCount - waitCount;
        } else {
            canUseCount = recordBean.getCanSellCount() + inputCount - waitCount;
        }
        if (canUseCount < count) {
            Long product = null;
            try {
                product = getSubProductId(commoditySku, shopDao.selectById(shopId).getCompanyId());
            } catch (Exception e) {
                return;
            }
            wrapper.eq(StockRecordDo::getProductInfoId, product);
            recordBean = mStockRecordDao.selectOne(wrapper);
            if (recordBean == null || recordBean.getCanSellCount() < 1 || recordBean.getCanSellCount() - waitCount < count) {
                throw new BizException(SysConstant.Product_Stock_NotEnough_Sku, commoditySku);
            }
        }
    }

    private Long getSubProductId(String sellerSku, Long companyId) {
        QueryWrapper skuWrapper = new QueryWrapper();
        skuWrapper.eq("sub_sku", sellerSku);
        skuWrapper.eq("company_id", companyId);
        ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
        if (productSkuMapDo == null) return 0L;
        return productSkuMapDo.getProductInfoId();
    }

    //新增校验
    private String addCheck(FbaOrderOutputAddReq req) {
//        if (!StringUtils.isNotBlank(req.getPostCode()))
//            throw new BizException("缺少邮编");
//        if (!StringUtils.isNotBlank(req.getAddress()))
//            throw new BizException("缺少收货地址");
//        if (!StringUtils.isNotBlank(req.getOrderNo()))
//            throw new BizException("缺少顾客订单号");
        if (req.getShopId() == null) throw new BizException(SysConstant.Order_No_Shop);
        if (req.getStorageId() == null) throw new BizException(SysConstant.Order_No_Storage);
        if (req.getPackageList() == null || req.getPackageList().size() < 1) {
            throw new BizException(SysConstant.Order_No_Product);
        }
        if (req.getFbaStorageId() == null && req.getStorageType() != null && req.getStorageType().equals("fba")) {
            throw new BizException(SysConstant.Pls_Choose_Fba_Storage);
        }
        if (req.getTrackId() == null) {
            throw new BizException(SysConstant.Pls_Choose_Track);
        }

        return null;
    }

    private String checkOrderNo(String orderNo, List<OrderOutputProductAddReq> productList) {
//        Map wrapper = new HashMap();
//        wrapper.put("keyword", orderNo);
//        List<OrderOutputDo> list = baseMapper.selectList(wrapper);
//        if (list == null || list.size() < 1) {
//            return null;
//        } else {
//            for (OrderOutputDo orderOutputDo :
//                    list) {
//                for (OrderOutputProductAddReq productAdd :
//                        productList) {
//                    LambdaQueryWrapper<OrderOutputProductDo> productWrapper = new LambdaQueryWrapper<>();
//                    productWrapper.eq(OrderOutputProductDo::getProductId, productAdd.getProductId());
//                    productWrapper.eq(OrderOutputProductDo::getOrderId, orderOutputDo.getId());
//                    List<OrderOutputProductDo> productDoList = productDao.selectList(productWrapper);
//                    if (productDoList != null && productDoList.size() > 0) {
//                        return String.format("%s(%s)已存在", orderNo, productInfoDao.selectById(productAdd.getProductId()).getCommoditySku());
//                    }
//                }
//            }
//            return null;
//        }
        return null;
    }

    //做新增之前要执行的业务定制处理
    private void handlerAddBefore(FbaOrderOutputDo entityDo, Long userId) {
        entityDo.setCreateBy(userId);
        entityDo.setCreateTime(new Date());
        entityDo.setSendDate(new Date());
        entityDo.setStatus(DicBusinessItemConstant.fbaInCreateState);
        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
    }


    @Override
    public SingleResult updateInit(Long id, Long companyId) {
        Map<String, Object> map = new HashMap<>();
        map.put("storage", storageService.getList(new HashMap<>()));
        map.put("region", regionService.getList(new HashMap<>()));
        map.put("companyTree", companyService.tree());


        //fbaStorage
        QueryWrapper wrapper1 = new QueryWrapper();
        wrapper1.orderByAsc("fba_code");
        List<FbaStorageDo> fbaStorageDos = fbaStorageDao.selectList(wrapper1);
        List<Map> fbaStorageList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(fbaStorageDos)) {
            fbaStorageDos.forEach(fbaStorageDo -> {
                Map fbaMap = new HashMap();
                fbaMap.put("id", fbaStorageDo.getId());
                fbaMap.put("code", fbaStorageDo.getFbaCode());
                fbaMap.put("name", fbaStorageDo.getFbaName());
                fbaMap.put("address", fbaStorageDo.getAddress());
                fbaMap.put("postCode", fbaStorageDo.getPostCode());
                fbaMap.put("tel", fbaStorageDo.getTelPhone());
                fbaStorageList.add(fbaMap);
            });
        }
        map.put("fbaStorageList", fbaStorageList);

        List<ShippingAddressDo> addressList;
        if (companyId == null) {
            addressList = shippingAddressDao.selectList(new QueryWrapper<ShippingAddressDo>());
        } else {
            addressList = shippingAddressDao.selectList(new QueryWrapper<ShippingAddressDo>().eq("company_id", companyId));
        }
        List<Map> resList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(addressList)) {
            addressList.forEach(addressDo -> {
                Map map1 = new HashMap();
                map1.put("id", addressDo.getId());
                map1.put("name", addressDo.getContact());
                map1.put("companyName", addressDo.getCompanyName());
                map1.put("address", addressDo.getAddress());
                map1.put("postCode", addressDo.getPostCode());
                map1.put("tel", addressDo.getTelPhone());
                resList.add(map1);
            });
        }
        map.put("ownAddressList", resList);


        FbaOrderOutputDetailRes detailRes = detail(id);
        map.put("detail", detailRes);
        return SingleResult.success(map);
    }

    @Override
    public FbaOrderOutputUpdateReq update(FbaOrderOutputUpdateReq req, Long userId) {
        updateCheck(req);

        FbaOrderOutputDo entityDo = dao.selectById(req.getId());
        if (entityDo == null) throw new BizException(SysConstant.Order_OrderNo_Null);
        if (entityDo.getStatus() >= DicBusinessItemConstant.fbaOrderSendOutStatus && entityDo.getStatus() != DicBusinessItemConstant.fbaOrderProblemStatus)
            throw new BizException(SysConstant.Order_Update_HadSend);

        if (req.getFileId() == null) {
            fileService.deleteFile(entityDo.getFileId());
        } else if (!req.getFileId().equals(entityDo.getFileId())) {
            fileService.uploadFile2(req.getFileId(), entityDo.getFileId());
        }
        if (req.getProductFileId() == null) {
            fileService.deleteFile(entityDo.getProductFileId());
        } else if (!req.getProductFileId().equals(entityDo.getProductFileId())) {
            fileService.uploadFile2(req.getProductFileId(), entityDo.getProductFileId());
        }
        if (req.getOtherFileId() == null) {
            fileService.deleteFile(entityDo.getOtherFileId());
        } else if (!req.getOtherFileId().equals(entityDo.getOtherFileId())) {
            fileService.uploadFile2(req.getOtherFileId(), entityDo.getOtherFileId());
        }
        BeanUtils.copyProperties(req, entityDo);
        if (StringUtils.isNotBlank(req.getDeliveryDate())) {
            entityDo.setDeliveryDate(TimeUtils.parseDate(req.getDeliveryDate()));
        } else {
            entityDo.setDeliveryDate(null);
        }
        if (entityDo.getStatus() == DicBusinessItemConstant.fbaOrderProblemStatus) {
            entityDo.setStatus(DicBusinessItemConstant.fbaInCreateState);
        }
        handlerUpdateBefore(entityDo, userId);

        //如果关联了拣货单 则不能修改包裹数量 sku数量
        handlerUpdateAfter(entityDo, req);
        //日志操作
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_UPDATE_FBA_ORDER, entityDo.getId(), userId, 6);

//        operateRecord("修改", entityDo.getId(), userId);
        handlerFee(entityDo, req.getTrackId());
        dao.updateById(entityDo);

        //编辑拼柜的po号
        executor.execute(() -> {
            LambdaQueryWrapper<TailTrucksDetailDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(TailTrucksDetailDo::getOrderId, req.getId());
            List<TailTrucksDetailDo> tailTrucksDetailDos = tailTrucksDetailDao.selectList(wrapper);
            if (!CollectionUtils.isEmpty(tailTrucksDetailDos)) {
                tailTrucksService.updatePoNumberHandler(tailTrucksDetailDos.get(0).getTrucksId());
            }
        });
        return req;
    }

    @Override
    public void appointmentStorageTime(FbaOrderOutputUpdateTimeReq req, Long currentUserId) {
        FbaOrderOutputDo orderOutputDo = dao.selectById(req.getId());
        orderOutputDo.setAppointmentStorageTime(DateFormater.strToDate(req.getDate()));
        if (orderOutputDo.getStatus() < DicBusinessItemConstant.fbaOrderAppointStorageStatus)
            orderOutputDo.setStatus(DicBusinessItemConstant.fbaOrderAppointStorageStatus);
        dao.updateById(orderOutputDo);
        operateRecordDao.operateAddRecordAndValue(SysConstant.OPERATE_UPDATE_FBA_INPUT_DATE, req.getDate(), req.getId(), currentUserId, 6);

//        updateTrackOrderTime("约仓", req.getId(), req.getDate(), currentUserId);
    }
//
//    public boolean updateTrackOrderTime(String operate, Long id, String time, Long currentUserId) {
//        FbaOrderOutputDetailRes res = detail(id);
//        OperateRecordDo operateRecordDo = new OperateRecordDo();
//        operateRecordDo.setDeleteFlag(0);
//        operateRecordDo.setThirdId(id);
//        operateRecordDo.setType(6);
//        operateRecordDo.setOperateBy(currentUserId);
//        operateRecordDo.setOperateTime(new Date());
//        operateRecordDo.setContent("更新了" + operate + "时间:" + time);
//        operateRecordDo.setRemarks(JSON.toJSONString(res));
//        operateRecordDao.insert(operateRecordDo);
//        return true;
//    }

    @Override
    public void appointmentCarTime(FbaOrderOutputUpdateTimeReq req, Long currentUserId) {
        FbaOrderOutputDo orderOutputDo = dao.selectById(req.getId());
        orderOutputDo.setAppointmentCarTime(DateFormater.strToDate(req.getDate()));
        if (orderOutputDo.getStatus() < DicBusinessItemConstant.fbaOrderAppointCarStatus)
            orderOutputDo.setStatus(DicBusinessItemConstant.fbaOrderAppointCarStatus);
        dao.updateById(orderOutputDo);
        operateRecordDao.operateAddRecordAndValue(SysConstant.OPERATE_UPDATE_FBA_TRAK_DATE, req.getDate(), req.getId(), currentUserId, 6);

//        updateTrackOrderTime("约车", req.getId(), req.getDate(), currentUserId);
    }

//    private void operateRecord(String operateStr, Long id, Long userId) {
//        FbaOrderOutputDetailRes res = detail(id);
//        OperateRecordDo operateRecordDo = new OperateRecordDo();
//        operateRecordDo.setDeleteFlag(0);
//        operateRecordDo.setThirdId(id);
//        operateRecordDo.setType(6);
//        operateRecordDo.setOperateBy(userId);
//        operateRecordDo.setOperateTime(new Date());
//        operateRecordDo.setContent(operateStr + "了fba转运订单");
//        operateRecordDo.setRemarks(JSON.toJSONString(res));
//        operateRecordDao.insert(operateRecordDo);
//    }

//    @Override
//    public void cutoff(Long id, Long userId) {
//        FbaOrderOutputDo entityDo = dao.selectById(id);
//        if (entityDo.getStatus() <= DicBusinessItemConstant.outCreateCheckState && entityDo.getStatus() >= DicBusinessItemConstant.outDelivered) {
//            throw new BizException("该订单未在发货途中或已签收，无法截单");
//        }
//        entityDo.setStatus(DicBusinessItemConstant.orderCutOff);
//
//        //日志操作
//        operateRecord("截断", entityDo.getId(), userId);
//
//        dao.updateById(entityDo);
//    }

    //编辑校验
    private void updateCheck(FbaOrderOutputUpdateReq req) {
//        if (!StringUtils.isNotBlank(req.getPostCode()))
//            throw new BizException("缺少邮编");
//        if (!StringUtils.isNotBlank(req.getAddress()))
//            throw new BizException("缺少收货地址");
//        if (!StringUtils.isNotBlank(req.getOrderNo()))
//            throw new BizException("缺少顾客订单号");
        if (req.getShopId() == null) throw new BizException(SysConstant.Order_No_Shop);
        if (req.getStorageId() == null) throw new BizException(SysConstant.Order_No_Storage);
        if (req.getFbaStorageId() == null && req.getStorageType() != null && req.getStorageType().equals("fba"))
            throw new BizException(SysConstant.Order_No_Storage);
        if (req.getTrackId() == null) {
            throw new BizException(SysConstant.Pls_Choose_Track);
        }
        if (req.getPackageList() == null || req.getPackageList().size() < 1) {
            throw new BizException(SysConstant.Order_No_Product);
        }
    }

    //做修改之前要执行的业务定制处理
    private void handlerUpdateBefore(FbaOrderOutputDo entityDo, Long userId) {
        entityDo.setUpdateBy(userId);
        entityDo.setUpdateTime(new Date());
    }

    //做修改之后要执行的业务定制处理
    private FbaOrderOutputUpdateReq handlerUpdateAfter(FbaOrderOutputDo entityDo, FbaOrderOutputUpdateReq updateReq) {
        if (entityDo.getPickStatus() == 0) {
            //未拣货
            LambdaQueryWrapper<FbaOrderOutputPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            packageDoLambdaQueryWrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, updateReq.getId());
            packageDao.delete(packageDoLambdaQueryWrapper);

            LambdaQueryWrapper<FbaOrderOutputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDoLambdaQueryWrapper.eq(FbaOrderOutputProductDo::getOrderId, updateReq.getId());
            productDao.delete(productDoLambdaQueryWrapper);

            List<FbaOrderOutputPackageUpdateReq> packageUpdateReqs = updateReq.getPackageList();
            StringBuilder sb = new StringBuilder();
            for (FbaOrderOutputPackageUpdateReq req : packageUpdateReqs) {
                FbaOrderOutputPackageDo packageDo = new FbaOrderOutputPackageDo();
                BeanUtils.copyProperties(req, packageDo);
                packageDo.setCount(req.getPackageCount());
                packageDo.setFbaOrderOutputId(updateReq.getId());
                if (!sb.toString().contains(req.getPoNumber())) {
                    if (sb.length() > 0) {
                        sb.append(",");
                    }
                    sb.append(req.getPoNumber());
                }
                packageDao.insert(packageDo);
                for (FbaOrderOutputProductDetail product : req.getProductList()) {
                    ProductInfoDo productInfoDo = productInfoDao.selectById(product.getProductId());
                    String commoditySKu = product.getCommoditySku();
                    if (productInfoDo != null) commoditySKu = productInfoDo.getCommoditySku();
                    FbaOrderOutputProductDo productDo = new FbaOrderOutputProductDo();
                    BeanUtils.copyProperties(product, productDo);
//                if (entityDo.getTrackId() == DicBusinessItemConstant.fbaTrackName2t ||
//                        entityDo.getTrackId() == DicBusinessItemConstant.fbaTrackName4t ||
//                        entityDo.getTrackId() == DicBusinessItemConstant.fbaTrackName10t) {
//                    // 吨车出库不验证库存数量
//                } else {
                    verifyStock(updateReq.getShopId(), updateReq.getStorageId(), product.getProductId(), packageDo.getCount() * product.getCount(), commoditySKu);
//                }
                    productDo.setOrderId(updateReq.getId());
                    productDo.setPackageId(packageDo.getId());
                    productDao.insert(productDo);
                }
            }
            entityDo.setPoNumber(sb.toString());
        }
        return updateReq;
    }

    @Override
    public int delete(Long id, Long userId) {
        FbaOrderOutputDo entityDo = dao.selectById(id);
        if (entityDo.getIsTrucks() == SysConstant.DELETE_FLAG_TRUE) {
            throw new BizException(SysConstant.FbaOrder_Delete_Error1);
        }
        //待拣货 未锁定库存
        if (entityDo.getPickStatus() == 1) {
            throw new BizException(SysConstant.FbaOrder_Delete_Error2);
        } else if (entityDo.getPickStatus() == 2) {
            throw new BizException(SysConstant.FbaOrder_Delete_Error3);
        }

        handlerDeleteBefore(entityDo, userId);
        return dao.deleteById(id);
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(FbaOrderOutputDo entityDo, Long userId) {
        entityDo.setDeleteBy(userId);
        entityDo.setDeleteTime(new Date());
        updateById(entityDo);
    }

    @Override
    public FbaOrderOutputDetailRes detail(Long id) {
        FbaOrderOutputDo entityDo = dao.selectById(id);
        FbaOrderOutputDetailRes res = new FbaOrderOutputDetailRes();
        if (entityDo == null) throw new BizException(SysConstant.Order_Detail_Notfound);
        BeanUtils.copyProperties(entityDo, res);
        DicBusinessItemDo itemDo = dicBusinessItemDao.selectById(entityDo.getStatus());
        if (itemDo != null) {
            res.setStatus(itemDo.getDicItemValue());
            res.setStatusId(itemDo.getId().intValue());
        }
        res.setFileUrl(fileService.getFilePath(entityDo.getFileId()));
        res.setProductFileUrl(fileService.getFilePath(entityDo.getProductFileId()));
        res.setOtherFileUrl(fileService.getFilePath(entityDo.getOtherFileId()));
        res.setTrackFileUrl(fileService.getFilePath(entityDo.getTrackFileId()));
        res.setSignatureFileUrl(fileService.getFilePath(entityDo.getSignatureFileId()));
        res.setSendList(this.getSendMsg(entityDo.getFbaOrderOutputNumber()));
        return handlerDetailAfter(entityDo, res);
    }

    public List<ProductStockFlowingRes> getSendMsg(String orderNo) {
        List<ProductStockFlowingDo> flowingDoList = productStockFlowingDao.selectList(new LambdaQueryWrapper<ProductStockFlowingDo>().eq(ProductStockFlowingDo::getNoteNo, orderNo).and(i -> i.eq(ProductStockFlowingDo::getType, StaticDict.Product_Flowing_Type.FbaOutput.getValue()).or().eq(ProductStockFlowingDo::getType, StaticDict.Product_Flowing_Type.FbaOutputRoll.getValue())).orderByDesc(ProductStockFlowingDo::getId));
        List<ProductStockFlowingRes> resList = productStockFlowingService.getResList(flowingDoList);
        return resList;
    }

    //查询明细之后要执行的业务定制处理
    private FbaOrderOutputDetailRes handlerDetailAfter(FbaOrderOutputDo entityDo, FbaOrderOutputDetailRes res) {
        res.setShopId(entityDo.getShopId());
        ShopDo shopDo = shopDao.selectById(entityDo.getShopId());
        if (shopDo != null) {
            res.setShop(shopDo.getShopName());
        }
        StorageDo storageDo = storageDao.selectById(entityDo.getStorageId());
        if (storageDo != null) {
            res.setStorage(storageDo.getStorageName());
        }
        if (entityDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
            FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(entityDo.getFbaStorageId());
            if (fbaStorageDo != null && entityDo.getReceiverName() == null) {
                res.setReceiverName(fbaStorageDo.getFbaCode() + " " + fbaStorageDo.getFbaName());
            }
        }
        if (dicBusinessItemDao.selectById(entityDo.getTrackId()) != null) {
            res.setTrackName(dicBusinessItemDao.selectById(entityDo.getTrackId()).getDicItemValue());
        }
        res.setPoNumber(entityDo.getPoNumber());
        res.setOrderNo(entityDo.getOrderNo());
        res.setOrderNumber(entityDo.getFbaOrderOutputNumber());
        if (entityDo.getDeliveryDate() != null) res.setDeliveryDate(TimeUtils.formatDate(entityDo.getDeliveryDate()));
//        res.setOrderTypeName(entityDo.getOrderType() != null && entityDo.getOrderType() == 2 ? ORDER_OUTPUT_TYPE_2 : ORDER_OUTPUT_TYPE_1);
        res.setShipmentTypeName(entityDo.getShipmentType() != null && entityDo.getShipmentType() == 1 ? SHIPMENT_TYPE_1 : SHIPMENT_TYPE_0);
        //查询对应包裹列表
        //package
        List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(new LambdaQueryWrapper<FbaOrderOutputPackageDo>().eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, res.getId()));
        List<FbaOrderOutputPackageDetail> packageResList = new ArrayList<>();

        //获取库存
        Map<String, String> param = new HashMap<>();
        param.put("storageId", entityDo.getStorageId() + "");
        param.put("shopId", entityDo.getShopId() + "");
        List<StockRecordPageRes> stockList = stockRecordService.getList(param);
        Map<Long, List<StockRecordPageRes>> stockListMap = stockList.stream().collect(Collectors.groupingBy(StockRecordPageRes::getProductInfoId));

        for (FbaOrderOutputPackageDo packageDo : packageDoList) {
            FbaOrderOutputPackageDetail packageDetailRes = new FbaOrderOutputPackageDetail();
            BeanUtils.copyProperties(packageDo, packageDetailRes);
            packageDetailRes.setSize(packageDo.getLength() + "+" + packageDo.getWidth() + "+" + packageDo.getHeight());
            //product
            List<FbaOrderOutputProductDetail> productResList = new ArrayList<>();
            List<FbaOrderOutputProductDo> productDoList = productDao.selectList(new LambdaQueryWrapper<FbaOrderOutputProductDo>().eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId()));

            for (FbaOrderOutputProductDo productDetail : productDoList) {
                FbaOrderOutputProductDetail productDetailRes = new FbaOrderOutputProductDetail();
                BeanUtils.copyProperties(productDetail, productDetailRes);
                ProductInfoDo productInfoDo = productInfoDao.selectById(productDetail.getProductId());
                if (productInfoDo != null) {
                    productDetailRes.setCommoditySku(productInfoDo.getCommoditySku());
                    productDetailRes.setStorageSku(productInfoDo.getStorageSku());
                    productDetailRes.setCommodityName(productInfoDo.getCommodityName());
                    if (stockListMap.get(productInfoDo.getId()) != null) {
                        productDetailRes.setCanSellCount(stockListMap.get(productInfoDo.getId()).get(0).getCanSellCount() - stockListMap.get(productInfoDo.getId()).get(0).getNoDelivered() + packageDo.getCount() * productDetail.getCount());
                    } else {
                        productDetailRes.setCanSellCount(0);
                    }
                }

                productResList.add(productDetailRes);
            }
            packageDetailRes.setProductList(productResList);
            packageResList.add(packageDetailRes);
        }

        res.setPackageList(packageResList);


        //查询日志
        List<OperateRes> operateResList = operateRecordDao.getOperateList(entityDo.getId(), 6);
        res.setOperateResList(operateResList);
        return res;
    }

    @Override
    public SingleResult pageInit(Long companyId, Long userId) {
        Map map = new HashMap();
        map.put("storageList", storageService.getList(new HashMap<>()));
        List<Long> ids = new ArrayList<>();
        LambdaQueryWrapper<DicBusinessItemDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.fbaOrderOutPutTruck);
        List<DicBusinessItemDo> trackCompanyList = dicBusinessItemDao.selectList(wrapper);
        List<IdAndNameEntity> trackList = new ArrayList<>();
        trackList.add(new IdAndNameEntity(DicBusinessItemConstant.sagawaExpress.intValue(), dicBusinessItemDao.selectById(DicBusinessItemConstant.sagawaExpress).getDicItemValue()));
        trackList.add(new IdAndNameEntity(DicBusinessItemConstant.yamatoExpress.intValue(), dicBusinessItemDao.selectById(DicBusinessItemConstant.yamatoExpress).getDicItemValue()));
        for (DicBusinessItemDo itemDo : trackCompanyList) {
            trackList.add(new IdAndNameEntity(itemDo.getId().intValue(), itemDo.getDicItemValue()));
        }
        map.put("trackList", trackList);
        List<Map> shopList = shopService.selectShopListInit(userId, companyId);
        List<Map> companyList = companyService.getInitList(companyId);
        map.put("shopList", companyList);
        //fbaStorage
        QueryWrapper wrapper1 = new QueryWrapper();
        wrapper1.orderByAsc("fba_code");
        List<FbaStorageDo> fbaStorageDos = fbaStorageDao.selectList(wrapper1);
        List<Map> fbaStorageList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(fbaStorageDos)) {
            fbaStorageDos.forEach(fbaStorageDo -> {
                Map fbaMap = new HashMap();
                fbaMap.put("id", fbaStorageDo.getId());
                fbaMap.put("value", fbaStorageDo.getFbaCode());
                fbaStorageList.add(fbaMap);
            });
        }
        map.put("fbaStorageList", fbaStorageList);

        List<Map> pickUpStatusList = new ArrayList<>();
        for (StaticDict.Pick_Up_Status value : StaticDict.Pick_Up_Status.values()) {
            Map pickMap = new HashMap();
            pickMap.put("id", value.getValue());
            pickMap.put("value", value.getText());
            pickUpStatusList.add(pickMap);
        }
        map.put("pickUpStatusList", pickUpStatusList);
        return SingleResult.success(map);
    }

    @Override
    public List<Map> uploadExcelInit(Long userid) {
        Map map = new HashMap();
        map.put("storageList", storageService.getList(new HashMap<>()));
        List<Map> shopList = new ArrayList<>();
        List<ShopDo> shopDoList = shopService.list();
        if (!CollectionUtils.isEmpty(shopDoList)) {
            for (ShopDo storageDo : shopDoList) {
                Map storageMap = new HashMap();
                storageMap.put("id", storageDo.getId());
                storageMap.put("value", storageDo.getShopName());
                shopList.add(storageMap);
            }
        }
        Map map1 = new HashMap();
        map1.put("shopList", shopList);
        List<Map> list = new ArrayList<>();
        list.add(map);
        list.add(map1);
        return list;
    }

    @Override
    public void uploadTrackNumberData(List<String> excelImportList, int storageId, Long userid) {

    }

    @Override
    public List<FbaOrderOutputListRes> getList(Map<String, String> map) {
        QueryWrapper<FbaOrderOutputDo> wrapper = queryBuild(map);
        List<FbaOrderOutputDo> list = this.list(wrapper);
        List<FbaOrderOutputListRes> result = handlerListAfter(list);
        return result;
    }

    @Override
    public PageResult getListPage(Map<String, String> map) {
        QueryWrapper<FbaOrderOutputDo> wrapper = queryBuild(map);
        IPage<FbaOrderOutputDo> page = pageInit(map);
        page = this.page(page, wrapper);
//        List<OrderOutputDo> orderOutputDoList = this.dao.listPage(page, map);
        List<FbaOrderOutputListRes> resList = handlerListAfter(page.getRecords());
        PageResult result = new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        result.setMapInfo(countStatus(map));
        return result;
    }

    private Map countStatus(Map<String, String> map) {
        List<Map> result = new ArrayList<>();
        map.put("status", "");

        Map mapTotal = new HashMap();
        List<FbaOrderOutputDo> list = dao.selectList(queryBuild(map));
        mapTotal.put("count", list.size());
        mapTotal.put("id", "");
        mapTotal.put("name", StringsUtil.createI18Message("全部"));
        result.add(mapTotal);

        Map<Long, List<FbaOrderOutputDo>> listMap = list.stream().collect(Collectors.groupingBy(FbaOrderOutputDo::getStatus));
        LambdaQueryWrapper<DicBusinessItemDo> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.fbaOrderOutputStatus);
        wrapper1.orderByAsc(DicBusinessItemDo::getSort);
        for (DicBusinessItemDo itemDo : dicBusinessItemDao.selectList(wrapper1)) {
            Map map1 = new HashMap();
            map1.put("id", itemDo.getId());
            if (listMap.get(itemDo.getId()) != null) {
                map1.put("count", listMap.get(itemDo.getId()).size());
            } else {
                map1.put("count", 0);
            }
            map1.put("name", StringsUtil.createI18Message(itemDo.getDicItemValue()));
            result.add(map1);
        }


        Map map2 = new HashMap();
        map2.put("census", result);
        return map2;
    }

    //查询分页列表之后对列表数据的处理
    private List<FbaOrderOutputListRes> handlerListAfter(List<FbaOrderOutputDo> list) {
        List<FbaOrderOutputListRes> result = new ArrayList<>();
        for (FbaOrderOutputDo orderOutputDo : list) {
            FbaOrderOutputListRes listRes = new FbaOrderOutputListRes();
            BeanUtils.copyProperties(orderOutputDo, listRes);
            StorageDo storageDo = storageDao.selectById(orderOutputDo.getStorageId());
            if (storageDo != null) {
                listRes.setStorageName(storageDo.getStorageName());
            }
            CompanyDo companyDo = companyDao.selectById(orderOutputDo.getCompanyId());
            if (storageDo != null) {
                listRes.setCompanyCode(companyDo.getCompanyCode());
            }
            if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
                FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
                if (fbaStorageDo != null) {
                    listRes.setFbaStorageName(fbaStorageDo.getFbaCode());
                }
            } else {
                listRes.setFbaStorageName(orderOutputDo.getReceiverName());
            }
            DicBusinessItemDo dic = dicBusinessItemDao.selectById(orderOutputDo.getTrackId());
            if (dic != null) {
                listRes.setTrackName(dic.getDicItemValue());
            }

            DicBusinessItemDo dicBusinessItemDo = dicBusinessItemDao.selectById(orderOutputDo.getStatus());
            if (dicBusinessItemDo != null) {
                listRes.setStatus(dicBusinessItemDo.getDicItemValue());
            }
            if (1 == orderOutputDo.getShipmentType()) {
                listRes.setShipmentTypeName(SHIPMENT_TYPE_1);
            } else {
                listRes.setShipmentTypeName(SHIPMENT_TYPE_0);
            }
            listRes.setCompanyCode(mCompanyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
            listRes.setNumber(orderOutputDo.getFbaOrderOutputNumber());
            listRes.setSendDate(TimeUtils.formatDate(orderOutputDo.getSendDate()));
            listRes.setVolume(getProductVolume(orderOutputDo));
            listRes.setWeight(getProductWeight(orderOutputDo));
            listRes.setShipPrice(orderOutputDo.getShipFee());
            listRes.setIsTrucks(orderOutputDo.getIsTrucks() != null && orderOutputDo.getIsTrucks() == 1 ? "已拼车" : "未拼车");
            if (orderOutputDo.getIsTrucks() == 1) {
                LambdaQueryWrapper<TailTrucksDetailDo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(TailTrucksDetailDo::getOrderId, orderOutputDo.getId());
                List<TailTrucksDetailDo> tailTrucksDetailDos = tailTrucksDetailDao.selectList(wrapper);
                if (!CollectionUtils.isEmpty(tailTrucksDetailDos)) {
                    TailTrucksDo tailTrucksDo = tailTrucksService.getBaseMapper().selectById(tailTrucksDetailDos.get(0).getTrucksId());
                    if (tailTrucksDo != null) {
                        listRes.setFbaTrucksNumber(tailTrucksDo.getTrucksNumber());
                    }
                }
            }

            if (orderOutputDo.getDeliveryDate() != null)
                listRes.setDeliveryDate(TimeUtils.formatDate(orderOutputDo.getDeliveryDate()));

            int packageCount = 0;
            int productCount = 0;
            Set<String> poSet = new HashSet<>();


            LambdaQueryWrapper<FbaOrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
            List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
            if (!CollectionUtils.isEmpty(packageDoList)) {
                packageCount = packageDoList.stream().mapToInt(FbaOrderOutputPackageDo::getCount).sum();
                double packageVolume = 0;
                double packageWeight = 0;
                for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                    poSet.add(packageDo.getPoNumber());
                    packageVolume += packageDo.getCount() * packageDo.getWidth() * packageDo.getLength() * packageDo.getHeight() / 1000000;
                    packageWeight += packageDo.getWeight() * packageDo.getCount();
                    LambdaQueryWrapper<FbaOrderOutputProductDo> productWrapper = new LambdaQueryWrapper<>();
                    productWrapper.eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId());
                    List<FbaOrderOutputProductDo> orderOutputProductDoList = productDao.selectList(productWrapper);
                    if (!CollectionUtils.isEmpty(orderOutputProductDoList)) {
                        productCount += orderOutputProductDoList.stream().mapToInt(FbaOrderOutputProductDo::getCount).sum() * packageDo.getCount();
                    }
                }
                listRes.setPackageVolume(packageVolume);
                listRes.setPackageWeight(packageWeight);
            }
            if (StringUtils.isBlank(orderOutputDo.getPoNumber())) {//主表po为空再查询子表
                StringBuilder stringBuilder = new StringBuilder();
                if (!CollectionUtils.isEmpty(poSet)) {
                    List<String> poList = new ArrayList<>(poSet);
                    for (int i = 0; i < poList.size(); i++) {
                        if (i >= poList.size() - 1) {
                            stringBuilder.append(poList.get(i));
                        } else {
                            stringBuilder.append(poList.get(i) + ",");
                        }
                    }
                }
                listRes.setPoNumber(stringBuilder.toString());
            } else {
                listRes.setPoNumber(orderOutputDo.getPoNumber());
            }
            listRes.setPackageCount(packageCount);
            listRes.setProductCount(productCount);
            result.add(listRes);
        }
        return result;
    }

    private String getProductVolume(FbaOrderOutputDo orderOutputDo) {
        double volume = 0;
        LambdaQueryWrapper<FbaOrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
        List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(packageDoList)) {
            for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                volume += packageDo.getHeight() * packageDo.getWidth() * packageDo.getLength() * packageDo.getCount();
            }
        }

        BigDecimal b = new BigDecimal(volume / 1000000);
        double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

        return f1 + "m³";
    }

    private double getProductWeight(FbaOrderOutputDo orderOutputDo) {
        double weight = 0;
        LambdaQueryWrapper<FbaOrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
        List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(packageDoList)) {
            for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                weight += packageDo.getWeight() * packageDo.getCount();
            }
        }

        double f2 = new BigDecimal(weight).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();

        return f2;

//        double volume = 0;
//        LambdaQueryWrapper<OrderOutputProductDo> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(OrderOutputProductDo::getOrderId, orderOutputDo.getId());
//        List<OrderOutputProductDo> orderOutputProductDoList = productDao.selectList(wrapper);
//        if (!CollectionUtils.isEmpty(orderOutputProductDoList)) {
//            for (OrderOutputProductDo productDo : orderOutputProductDoList) {
//                ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
//                if (productInfoDo != null) {
//                    volume += (productInfoDo.getHeight() * productInfoDo.getWidth() * productInfoDo.getLength());
//                }
//            }
//        }
//        return f1;

    }

    private IPage<FbaOrderOutputDo> pageInit(Map<String, String> map) {
        IPage<FbaOrderOutputDo> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private QueryWrapper<FbaOrderOutputDo> queryBuild(Map<String, String> map) {
        QueryWrapper<FbaOrderOutputDo> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(map.get("keyword"))) {
            wrapper.or(orderOutputDoQueryWrapper -> orderOutputDoQueryWrapper.like("order_no", map.get("keyword")).or(true).like("fba_order_output_number", map.get("keyword")).or(true).like("tel_phone", map.get("keyword")).or(true).like("po_number", map.get("keyword").trim()).or(true).like("tips", map.get("keyword").trim()).or(true).like("track_number", map.get("keyword")));
        }
        if (StringUtils.isNotBlank(map.get("status"))) {
            wrapper.eq("status", map.get("status"));
        }
        if (StringUtils.isNotBlank(map.get("startDate"))) {
            wrapper.ge("send_date", map.get("startDate"));
        }
        if (StringUtils.isNotBlank(map.get("endDate"))) {
            wrapper.le("send_date", map.get("endDate"));
        }
        if (StringUtils.isNotBlank(map.get("storageId"))) {
            wrapper.eq("storage_id", map.get("storageId"));
        }
        if (StringUtils.isNotBlank(map.get("storageId1")) && StringUtils.isNotBlank(map.get("storageId2")) && StringUtils.isNotBlank(map.get("storageId3"))) {
            wrapper.and(fbaOrderOutputDoQueryWrapper -> {
                fbaOrderOutputDoQueryWrapper.eq("storage_id", map.get("storageId1")).or().eq("storage_id", map.get("storageId2")).or().eq("storage_id", map.get("storageId3"));
            });
        }
        if (StringUtils.isNotBlank(map.get("fbaStorageId"))) {
            wrapper.eq("fba_storage_id", map.get("fbaStorageId"));
        }
        if (StringUtils.isNotBlank(map.get("trackId"))) {
            wrapper.eq("track_id", map.get("trackId"));
        }
        if (StringUtils.isNotBlank(map.get("isSendOut"))) {
            wrapper.lt("status", map.get("isSendOut"));
        }
        if (StringUtils.isNotBlank(map.get("companyId"))) {
            wrapper.eq("company_id", map.get("companyId"));
        }
        if (StringUtils.isNotBlank(map.get("isTrucks"))) {
            wrapper.eq("is_trucks", map.get("isTrucks"));
        }

        if (StringUtils.isNotBlank(map.get("pickStatus"))) {
            wrapper.eq("pick_Status", map.get("pickStatus"));
        }


        wrapper.orderByDesc("send_date").orderByAsc("fba_storage_id");
        return wrapper;
    }

    @Override
    public List<String> dealwithTrackNumberExcel(MultipartFile file, Integer storageId, Long userid) {
        List<OrderOutputTrackNumberExcelImport> excelImportList = new ArrayList<>();
        if (StringUtils.isEmpty(file.getName())) {
            throw new BizException(SysConstant.File_Name_Null);
        }
        if (storageId == 0) throw new BizException(SysConstant.Pls_Choose_Send_Storage);
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if (!GlobalConstants.IMG_TYPE_XLS.equals(suffix.toUpperCase()) && !GlobalConstants.IMG_TYPE_XLSX.equals(suffix.toUpperCase())) {
            throw new BizException(SysConstant.File_Form_Incorrect);
        }
        try {
            excelImportList = ExcelUtils.importExcel(file, 0, 0, OrderOutputTrackNumberExcelImport.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (excelImportList == null || excelImportList.size() == 0) {
            throw new BizException(SysConstant.File_FormWork_Incorrect);
        }

        return dealwithExcelData(excelImportList, storageId, userid);
    }

    @Override
    public void exportExcel(Map<String, String> map, List<Long> ids, HttpServletResponse response) throws IOException {
        QueryWrapper<FbaOrderOutputDo> wrapper = queryBuild(map);
        List<FbaOrderOutputDo> orderOutputDoList;
        if (ids != null && ids.size() > 0) {
            orderOutputDoList = this.baseMapper.selectBatchIds(ids);
        } else {
            orderOutputDoList = this.baseMapper.selectList(wrapper);
        }
        if (orderOutputDoList.size() > 2000) {
//            response.setStatus();
            response.sendError(500, "数据超过2000条，请分日期导出");
            throw new BizException();
        }
        List<FbaOrderOutputExcelExportVo> excelExportVoList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(orderOutputDoList)) {
            for (FbaOrderOutputDo orderOutputDo : orderOutputDoList) {
                FbaOrderOutputExcelExportVo excelExportVo = new FbaOrderOutputExcelExportVo();

                BeanUtils.copyProperties(orderOutputDo, excelExportVo);

                DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(orderOutputDo.getStatus());
                if (businessItemDo != null) {
                    excelExportVo.setStatus(businessItemDo.getDicItemValue());
                }
                ShopDo shopDo = shopDao.selectById(orderOutputDo.getShopId());
                if (shopDo != null) {
                    excelExportVo.setShopName(shopDo.getShopName());
                }
                StorageDo storageDo = storageDao.selectById(orderOutputDo.getStorageId());
                if (storageDo != null) {
                    excelExportVo.setStorageName(storageDo.getCode());
                }
                CompanyDo companyDo = companyDao.selectById(orderOutputDo.getCompanyId());
                if (companyDo != null) {
                    excelExportVo.setCompanyName(companyDo.getCompanyCode());
                }
                FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
                if (fbaStorageDo != null) {
                    excelExportVo.setFbaStorageCode(fbaStorageDo.getFbaCode() + " " + fbaStorageDo.getFbaName());
                }
                DicBusinessItemDo track = dicBusinessItemDao.selectById(orderOutputDo.getTrackId());
                if (track != null) {
                    excelExportVo.setTrackName(track.getDicItemValue());
                }

                int packageCount = packageDao.selectCountByOrderId(orderOutputDo.getId());
                excelExportVo.setWeight(getProductWeight(orderOutputDo));
                excelExportVo.setVolume(getProductVolume(orderOutputDo));
                excelExportVo.setPackageCount((packageCount));
                //package
                LambdaQueryWrapper<FbaOrderOutputPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                packageDoLambdaQueryWrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
                List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(packageDoLambdaQueryWrapper);
                if (!CollectionUtils.isEmpty(packageDoList)) {
                    List<FbaOrderOutputPackageExcelExportVo> packageExcelExportVoList = new ArrayList<>();
                    for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                        FbaOrderOutputPackageExcelExportVo packageExcelExportVo = new FbaOrderOutputPackageExcelExportVo();
                        BeanUtils.copyProperties(packageDo, packageExcelExportVo);
                        LambdaQueryWrapper<FbaOrderOutputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        productDoLambdaQueryWrapper.eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId());
                        List<FbaOrderOutputProductDo> productDoList = productDao.selectList(productDoLambdaQueryWrapper);
                        if (!CollectionUtils.isEmpty(productDoList)) {
                            List<FbaOrderOutputProductExcelExportVo> productExcelExportVoList = new ArrayList<>();
                            for (FbaOrderOutputProductDo productDo : productDoList) {
                                FbaOrderOutputProductExcelExportVo productExcelExportVo = new FbaOrderOutputProductExcelExportVo();
                                BeanUtils.copyProperties(productDo, productExcelExportVo);
                                ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                                if (productInfoDo != null) {
                                    productExcelExportVo.setCommoditySku(productInfoDo.getCommoditySku());
                                    productExcelExportVo.setProductName(productInfoDo.getProductName());
                                    productExcelExportVo.setStorageSku(productInfoDo.getStorageSku());
                                }
                                productExcelExportVoList.add(productExcelExportVo);
                            }
                            packageExcelExportVo.setProductExcelExportVoList(productExcelExportVoList);
                        }
                        packageExcelExportVoList.add(packageExcelExportVo);
                    }
                    excelExportVo.setPackageExcelExportVoList(packageExcelExportVoList);
                }
                excelExportVoList.add(excelExportVo);
            }
        }

        ExcelUtils.exportExcel(excelExportVoList, FbaOrderOutputExcelExportVo.class, "fba转运订单", new ExportParams(), response);
    }

    public List<String> dealwithExcelData(List<OrderOutputTrackNumberExcelImport> excelImportList, int storageId, Long userid) {
        List<String> orderNumbers = new ArrayList<>();
        Map<String, List<IdAndNameEntity>> orderMaps = new HashMap<>();
        for (int i = 0; i < excelImportList.size(); i++) {
            OrderOutputTrackNumberExcelImport excelData = excelImportList.get(i);
            if (excelData == null) continue;
            if (excelData.getOrderOTNumber() == null) continue;
            excelData.setOrderOTNumber(excelData.getOrderOTNumber().trim());
            if (excelData.getTrackNumber() == null) continue;
            excelData.setTrackNumber(excelData.getTrackNumber().trim());
            String key = "";
            int packageIndex = 0;
            if (excelData.getOrderOTNumber().contains("-")) {
                key = excelData.getOrderOTNumber().split("-")[0];
                packageIndex = Integer.parseInt(excelData.getOrderOTNumber().split("-")[1]);
            } else {
                key = excelData.getOrderOTNumber();
            }
            if (orderMaps.get(key) == null) {
                orderMaps.put(key, new ArrayList<>());
            }
            orderMaps.get(key).add(new IdAndNameEntity(packageIndex, excelData.getTrackNumber()));
        }
        for (String orderNumber : orderMaps.keySet()) {
            String totalNumber = new String();
            List<IdAndNameEntity> indexAndTrackNumberList = orderMaps.get(orderNumber);
            totalNumber = indexAndTrackNumberList.stream().map(idAndNameEntity -> idAndNameEntity.getValue()).collect(Collectors.joining(","));
            LambdaQueryWrapper<FbaOrderOutputDo> wrapper = new LambdaQueryWrapper();
            wrapper.eq(FbaOrderOutputDo::getFbaOrderOutputNumber, orderNumber);
            FbaOrderOutputDo outputDo = dao.selectOne(wrapper);
            if (outputDo == null) {
                wrapper = new LambdaQueryWrapper();
                wrapper.or(orderWrapper -> {
                    orderWrapper.eq(FbaOrderOutputDo::getOrderNo, orderNumber).or().eq(FbaOrderOutputDo::getReceiverName, orderNumber);
                });
                wrapper.eq(FbaOrderOutputDo::getStatus, DicBusinessItemConstant.fbaOrderPrintStatus);
                wrapper.orderByAsc(FbaOrderOutputDo::getCreateTime);
                wrapper.last("limit 1");
                outputDo = dao.selectOne(wrapper);
            }
            if (outputDo != null && !totalNumber.equals(outputDo.getTrackNumber())) {
                outputDo.setTrackNumber(totalNumber);
                outputDo.setUpdateBy(userid);
                outputDo.setUpdateTime(new Date());
                saveOrUpdate(outputDo);
                List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(new LambdaQueryWrapper<FbaOrderOutputPackageDo>()
                        .eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, outputDo.getId()));
                for (int i = 0; i < packageDoList.size(); i++) {
                    final int index = i + 1;
                    FbaOrderOutputPackageDo fbaOrderOutputPackageDo = packageDoList.get(i);
                    String trackNumber = indexAndTrackNumberList.stream().filter(track ->
                            track.getId() == index).map(IdAndNameEntity::getValue).collect(Collectors.joining(","));
                    fbaOrderOutputPackageDo.setTrackNumber(trackNumber);
                    fbaOrderOutputPackageDo.setUpdateBy(userid);
                    fbaOrderOutputPackageDo.setUpdateTime(new Date());
                    packageDao.updateById(fbaOrderOutputPackageDo);
                }
                if (DicBusinessItemConstant.fbaOrderPrintStatus.equals(outputDo.getStatus()) || DicBusinessItemConstant.fbaOrderAppointStorageStatus.equals(outputDo.getStatus()) || DicBusinessItemConstant.fbaOrderAppointCarStatus.equals(outputDo.getStatus())) {
                    //未关联拣货单 由前端给推荐库位，但是这边是导入，自己获取
                    if (outputDo.getPickUpId() == null) {

                        BatchPickUpReq pickUpReq = new BatchPickUpReq();
                        pickUpReq.setIds(Arrays.asList(outputDo.getId()));
                        List<BatchPickUpRes> resList = new ArrayList<>();
                        try {
                            //获取出库推荐库位
                            resList = this.batchPickUp(pickUpReq, userid, outputDo.getCompanyId());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (resList == null || resList.size() == 0) {
                            continue;
                        }
                        Long oldStatus = outputDo.getStatus();
                        this.dealwithOrderSendOut(outputDo, null, userid);
                        this.sendWhenOutWaitSendOut(resList.get(0).getPositionAndNumberList(), outputDo, oldStatus, userid, false);
                    }
                    //关联拣货单 但是 未完成拣货
//                    else if (outputDo.getPickUpId() != null && outputDo.getPickUpId() != 0 && outputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.UnPick.getValue())) {
//                        //先去完成拣货
//                        StockPickUpDo pickUpDo = stockPickUpDao.selectById(outputDo.getPickUpId());
//                        if (pickUpDo == null) {
//                            throw new BizException(SysConstant.FbaOrder_Pickup_NotMatch);
//                        }
//                        stockPickUpService.finishPickUp(pickUpDo, new HashSet<>(), userid, outputDo.getId());
//                        //再去正常出库，此时拣货单已拣货
//                        this.dealwithOrderSendOut(outputDo, null, userid);
//                    }
                    //已拣货
                    else if (outputDo.getPickUpId() != null && outputDo.getPickUpId() != 0 && !outputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.ToPick.getValue())) {
                        //操作旧表库存， 并且如果已拣货 顺便操作新表
                        this.dealwithOrderSendOut(outputDo, null, userid);
                    } else {
                        continue;
                    }
                    orderNumbers.add(outputDo.getFbaOrderOutputNumber());

                } else if (outputDo.getStatus().equals(DicBusinessItemConstant.fbaOrderProblemStatus)) {
                    //问题件
                    dealwithOrderSendOut(outputDo, null, userid);
                    orderNumbers.add(outputDo.getFbaOrderOutputNumber());
                }

            }
        }

//        if (orderNumbers.size() > 0)
//            autoUploadExpressNumber(orderNumbers);
//        executeTaskT(excelImportList);Amz
        return orderNumbers;
    }

    @Override
    public void dealwithOrderSendOut(FbaOrderOutputDo outputDo, Long trackId, Long userId) {
        if (!outputDo.getStatus().equals(DicBusinessItemConstant.fbaOrderProblemStatus)) {
            // //查询 拣货单
            StockPickUpDo pickUpDo = stockPickUpDao.selectById(outputDo.getPickUpId());

            LambdaQueryWrapper<FbaOrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, outputDo.getId());
            List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);

            Map<Long, Integer> productMap = new HashMap<>();
            for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                LambdaQueryWrapper<FbaOrderOutputProductDo> wrapper1 = new LambdaQueryWrapper<>();
                wrapper1.eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId());
                List<FbaOrderOutputProductDo> productDoList = productDao.selectList(wrapper1);
                int totalCount = 0;
                for (FbaOrderOutputProductDo orderOutputProductDo : productDoList) {
                    LambdaQueryWrapper<StockRecordDo> stockWrapper = new LambdaQueryWrapper<>();
                    stockWrapper.eq(StockRecordDo::getProductInfoId, orderOutputProductDo.getProductId()).eq(StockRecordDo::getStorageId, outputDo.getStorageId()).eq(StockRecordDo::getShopId, outputDo.getShopId());
                    StockRecordDo stockRecordDo = mStockRecordDao.selectOne(stockWrapper);
                    if (stockRecordDo == null) {
                        ProductInfoDo productInfoDo = productInfoDao.selectById(orderOutputProductDo.getProductId());
                        throw new BizException(SysConstant.Product_Stock_NotEnough_Sku, productInfoDo == null ? "" : productInfoDo.getCommoditySku());
                    }
                    int count = orderOutputProductDo.getCount() * packageDo.getCount();
                    if (stockRecordDo.getCanSellCount() < count) {
                        ProductInfoDo productInfoDo = productInfoDao.selectById(orderOutputProductDo.getProductId());
                        throw new BizException(SysConstant.Product_Stock_NotEnough_Sku, productInfoDo == null ? "" : productInfoDo.getCommoditySku());
                    }
                    productMap.merge(orderOutputProductDo.getProductId(), count, Integer::sum);
                    stockRecordDo.setCanSellCount(stockRecordDo.getCanSellCount() - count);
                    stockRecordDo.setUpdateTime(new Date());
                    totalCount = totalCount + orderOutputProductDo.getCount();
                    mStockRecordDao.updateById(stockRecordDo);
                    mStockLogService.saveAutoSendOutLog(orderOutputProductDo.getProductId(), outputDo.getShopId(), outputDo.getStorageId(), -count, stockRecordDo.getCanSellCount(), outputDo.getCompanyId(), outputDo.getUpdateBy(), StringUtils.isBlank(outputDo.getOrderNo()) ? outputDo.getFbaOrderOutputNumber() : outputDo.getOrderNo());
                }
            }
            for (Long productId : productMap.keySet()) {
                //已拣货
                if (outputDo.getPickUpId() != null && !outputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.ToPick.getValue())) {
                    outputDo.setPickStatus(StaticDict.Pick_Up_Status.Picked.getValue());
                    if (pickUpDo == null) {
                        throw new BizException(SysConstant.FbaOrder_Pickup_NotMatch);
                    }
                    SendRes res = productOutService.dealStockAfterSendOut(outputDo.getId(), outputDo.getFbaOrderOutputNumber(), StaticDict.Product_Flowing_Type.FbaOutput.getValue(), StaticDict.Product_Flowing_Type.FbaOutput.getValue(), productMap.get(productId), productId, outputDo.getStorageId(), outputDo.getShopId(), pickUpDo.getId(), outputDo.getCompanyId(), userId);
                    if (res.getCode() != 200) {
                        throw new BizException(res.getMsg());
                    }
                    if (pickUpDo.getStatus() != 1) {
                        pickUpDo.setStatus(1);
                        pickUpDo.setPickUpBy(userId);
                        pickUpDo.setPickUpTime(new Date());
                        stockPickUpDao.updateById(pickUpDo);
                    }
                }
            }

        }
        Integer count = 0;
        StringBuilder content = new StringBuilder(outputDo.getFbaOrderOutputNumber() + "订单转运");
        if (outputDo.getIsTrucks() == 1) {
            LambdaQueryWrapper<FbaOrderOutputDo> fbaOrderOutputDoWrapper = new LambdaQueryWrapper<>();
//            LambdaQueryWrapper<TailTrucksDetailDo> tailTrucksWrapper = new LambdaQueryWrapper<>();
//            tailTrucksWrapper.eq(TailTrucksDetailDo::getOrderId, outputDo.getId());
            List<Long> truckOrderIds = tailTrucksDetailDao.getTruckOrderId(outputDo.getId());
            if (truckOrderIds != null && truckOrderIds.size() > 0) {
                fbaOrderOutputDoWrapper.ge(FbaOrderOutputDo::getStatus, DicBusinessItemConstant.fbaOrderSendOutStatus).eq(FbaOrderOutputDo::getCompanyId, outputDo.getCompanyId()).eq(FbaOrderOutputDo::getTrackId, outputDo.getTrackId()).ne(FbaOrderOutputDo::getId, outputDo.getId()).in(FbaOrderOutputDo::getId, truckOrderIds);
                count = baseMapper.selectCount(fbaOrderOutputDoWrapper);
            }
        }

        handlerFee(outputDo, trackId);
        if (count != null && count > 0) {
            content.append("+拼车" + outputDo.getTrackNumber());
            outputDo.setShipFee(0);
            outputDo.setOriginShipFee(0);
            outputDo.setTaxFee((outputDo.getOperateFee() + outputDo.getOutFee()) * 0.1);
        }
        double totalFee = outputDo.getShipFee() + outputDo.getOperateFee() + outputDo.getOutFee() + outputDo.getTaxFee();
        mCostService.add(5, content.toString(), totalFee, outputDo.getShopId(), outputDo.getCompanyId(), outputDo.getId());
        //更新状态
        outputDo.setStatus(DicBusinessItemConstant.fbaOrderSendOutStatus);
        outputDo.setSendTime(new Date());
        updateById(outputDo);
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_SEND_FBA, outputDo.getId(), userId, 6);

//        operateRecord("发货", outputDo.getId(), outputDo.getUpdateBy());
    }

    private void dealwithOrderOutBack(FbaOrderOutputDo orderOutputDo, Long trackId) {
        //todo 其他改为未发货  加库存和加费用  删去一些信息
        LambdaQueryWrapper<FbaOrderOutputPackageDo> orderOutputPackageWrapper = new LambdaQueryWrapper<>();
        orderOutputPackageWrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
        //得到此订单下的所有包裹
        List<FbaOrderOutputPackageDo> orderOutputPackageDos = packageDao.selectList(orderOutputPackageWrapper);
        for (FbaOrderOutputPackageDo orderOutputPackageDo : orderOutputPackageDos) {
            LambdaQueryWrapper<FbaOrderOutputProductDo> orderOutputProductWrapper = new LambdaQueryWrapper<>();
            orderOutputProductWrapper.eq(FbaOrderOutputProductDo::getOrderId, orderOutputDo.getId()).eq(FbaOrderOutputProductDo::getPackageId, orderOutputPackageDo.getId());
            List<FbaOrderOutputProductDo> orderOutputProductDos = productDao.selectList(orderOutputProductWrapper);
            //包裹下的所有商品
            for (FbaOrderOutputProductDo orderOutputProductDo : orderOutputProductDos) {
                LambdaQueryWrapper<StockRecordDo> stockWrapper = new LambdaQueryWrapper();
                stockWrapper.eq(StockRecordDo::getProductInfoId, orderOutputProductDo.getProductId()).eq(StockRecordDo::getStorageId, orderOutputDo.getStorageId()).eq(StockRecordDo::getShopId, orderOutputDo.getShopId());
                List<StockRecordDo> stockRecordDoList = mStockRecordDao.selectList(stockWrapper);
                if (stockRecordDoList != null && stockRecordDoList.size() > 0) {
                    StockRecordDo stockRecordDo = stockRecordDoList.get(0);
                    if (stockRecordDo != null) {
                        stockRecordDo.setCanSellCount(stockRecordDo.getCanSellCount() + orderOutputProductDo.getCount() * orderOutputPackageDo.getCount());
                        stockRecordDo.setUpdateTime(new Date());
//                                totalCount = totalCount + orderOutputProductDo.getCount();
                        mStockRecordDao.updateById(stockRecordDo);
                        mStockLogService.saveAutoSendOutLog(orderOutputProductDo.getProductId(), orderOutputDo.getShopId(), orderOutputDo.getStorageId(), orderOutputProductDo.getCount() * orderOutputPackageDo.getCount(), stockRecordDo.getCanSellCount(), orderOutputDo.getCompanyId(), orderOutputDo.getUpdateBy(), orderOutputDo.getOrderNo());
                    }
                }
            }
        }
        //店铺
        LambdaQueryWrapper<CompanyAccountDo> companyAccountWrapper = new LambdaQueryWrapper<>();
        companyAccountWrapper.eq(CompanyAccountDo::getCompanyId, orderOutputDo.getCompanyId());
        //公司账户
        CompanyAccountDo companyAccountDo = companyAccountService.getBaseMapper().selectOne(companyAccountWrapper);
        //对费用操作
        Double sum = 0D;
        if (orderOutputDo.getShipFee() != 0) {
            sum = sum + orderOutputDo.getShipFee() + orderOutputDo.getOutFee() + orderOutputDo.getOperateFee() + orderOutputDo.getTaxFee();
            orderOutputDo.setShipFee(0D);
            orderOutputDo.setOutFee(0D);
            orderOutputDo.setOperateFee(0D);
            orderOutputDo.setTaxFee(0D);
        }
        companyAccountDo.setCompanyAccount(companyAccountDo.getCompanyAccount() + sum);
        companyAccountService.getBaseMapper().updateById(companyAccountDo);
        //出库订单也更新一下
        //做一下记录
        CostRecordDo costRecordDo = new CostRecordDo();
        costRecordDo.setType(0);
        costRecordDo.setContent(orderOutputDo.getFbaOrderOutputNumber() + "退返");
        costRecordDo.setAfterAmount(companyAccountDo.getCompanyAccount());
        costRecordDo.setCostAmount(-sum);
        costRecordDo.setCompanyId(companyAccountDo.getCompanyId() + "");
        costRecordDo.setShopId(orderOutputDo.getShopId());
        costRecordDo.setStatus(1);
        costRecordDo.setThirdId(orderOutputDo.getId() + "");
        costRecordDo.setCreateTime(new Date());
        costRecordDo.setPayTime(new Date());
        costRecordDo.setUpdateTime(new Date());
        mCostService.getBaseMapper().insert(costRecordDo);
        updateById(orderOutputDo);
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_ROLL_FBA_ORDER, orderOutputDo.getId(), orderOutputDo.getUpdateBy(), 6);
//        operateRecord("回滚", orderOutputDo.getId(), orderOutputDo.getUpdateBy());
    }

    private boolean verifyMaxSize(double[] size, Long companyId) {
        if (companyId == 1) {
            return size[0] + size[1] + size[2] > 260 || size[3] > 100;
        } else {
            return size[0] + size[1] + size[2] > SysConstant.OUT_MAX_MUTIL_PACKAGE_SIZE || size[3] > SysConstant.OUT_MAX_MUTIL_PACKAGE_WEIGHT;
        }
    }


    private void updateFBATrackId(FbaOrderOutputDo outputDo) {
        List<OrderOutputPackageDo> packageDoListCount = new ArrayList<>();
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_id", outputDo.getId());
        List<OrderOutputProductDo> productDoList = productDao.selectList(wrapper);
    }

    @Override
    public SingleResult updateOrderWaitSend(Map<String, String> map, List<Long> ids, HttpServletResponse response) {
        QueryWrapper<FbaOrderOutputDo> wrapper = queryBuild(map);

        List<FbaOrderOutputDo> orderOutputDoList;
        if (ids != null && ids.size() > 0) {
            orderOutputDoList = this.baseMapper.selectBatchIds(ids);
        } else {
            orderOutputDoList = this.baseMapper.selectList(wrapper);
        }
//        List<Long> orderIds = new ArrayList<>();
        orderOutputDoList = orderOutputDoList.stream()
//                .filter(orderOutputDo -> orderOutputDo.getStatus() == DicBusinessItemConstant.outCreateCheckState ||
//                orderOutputDo.getStatus() == DicBusinessItemConstant.outCreateState)
                .map(orderOutputDo -> {
                    orderOutputDo.setStatus(DicBusinessItemConstant.fbaOrderPrintStatus);
                    orderOutputDo.setUpdateTime(new Date());
                    return orderOutputDo;
                }).collect(Collectors.toList());
        boolean b = updateBatchById(orderOutputDoList);
        return b ? SingleResult.success() : SingleResult.failure("更新失败，请联系管理员");
    }

    @Override
    public SingleResult exportTrackExpress(Map<String, String> map, List<Long> ids, HttpServletResponse response) throws IOException {
        QueryWrapper<FbaOrderOutputDo> wrapper = queryBuild(map);
        List<FbaOrderOutputDo> orderOutputDoList;
        if (ids != null && ids.size() > 0) {
            orderOutputDoList = this.baseMapper.selectBatchIds(ids);
        } else {
            orderOutputDoList = this.baseMapper.selectList(wrapper);
        }
        List<FbaOrderOutputSelfStorageExportVo> excelExportVoList = new ArrayList<>();
        List<OrderOutputSagawaExportVo> sagawaExportVoList = new ArrayList<>();
        List<OrderOutputYamatoExportVo> yamatoExportVoList = new ArrayList<>();
        List<FbaOrderOutputSeinoExportVo> seinoExportVoList = new ArrayList<>();
        List<FbaOutputExcelExportFeiyunVo> feiyunVoList = new ArrayList<>();
        switch (map.get("trackId")) {
            case "8":
                orderOutputDoList.stream().sorted(new Comparator<FbaOrderOutputDo>() {
                    @Override
                    public int compare(FbaOrderOutputDo o1, FbaOrderOutputDo o2) {
                        if (o1.getCommoditySku() == null || o2.getCommoditySku() == null) return 1;
                        return o1.getCommoditySku().compareTo(o2.getCommoditySku());
                    }
                }).forEach(orderOutputDo -> {
                    QueryWrapper wrapper1 = new QueryWrapper();
                    wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
                    List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper1);
                    sagawaExportVoList.add(buidSagawaExportData(orderOutputDo, packageDoList));
                });
                CsvExportParams exportParamsS = new CsvExportParams();
                exportParamsS.setCreateHeadRows(true);
                exportParamsS.setEncoding("Shift-JIS");
                CsvUtils.exportCsv(exportParamsS, OrderOutputSagawaExportVo.class, sagawaExportVoList, TimeUtils.getCurrentDateFormat() + "Sagawa Bto出荷依頼.csv", response);
//                        ExcelUtils.exportExcel(sagawaExportVoList, OrderOutputSagawaExportVo.class, TimeUtils.getCurrentDateFormat() + "Sagawa出荷依頼.xls", new ExportParams(), response);
                break;
            case "9":
                orderOutputDoList.stream().sorted(new Comparator<FbaOrderOutputDo>() {
                    @Override
                    public int compare(FbaOrderOutputDo o1, FbaOrderOutputDo o2) {
                        if (o1.getCommoditySku() == null || o2.getCommoditySku() == null) return 1;
                        return o1.getCommoditySku().compareTo(o2.getCommoditySku());
                    }
                }).forEach(orderOutputDo -> {
                    QueryWrapper wrapper1 = new QueryWrapper();
                    wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
                    List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper1);
                    sagawaExportVoList.add(buidSagawaExportData(orderOutputDo, packageDoList));
                });
                orderOutputDoList.forEach(orderOutputDo -> {
                    QueryWrapper<FbaOrderOutputPackageDo> wrapper1 = new QueryWrapper<>();
                    wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
                    List<FbaOrderOutputPackageDo> packageList = packageDao.selectList(wrapper1);
                    if (packageList != null && packageList.size() > 0) for (int i = 0; i < packageList.size(); i++) {
                        FbaOrderOutputPackageDo orderInputProductDo = packageList.get(i);
                        yamatoExportVoList.add(buildYamatoExportData(orderOutputDo, orderInputProductDo, i + 1));
                    }
                });
                //排序
//                yamatoExportVoList.sort(new Comparator<OrderOutputYamatoExportVo>() {
//                    @Override
//                    public int compare(OrderOutputYamatoExportVo o1, OrderOutputYamatoExportVo o2) {
//                        return trackExpressSort(map.get("storageId"), o1.getCommoditySku(), o2.getCommoditySku(), o1, o2);
//                    }
//                });
                ExcelUtils.exportExcel(yamatoExportVoList, OrderOutputYamatoExportVo.class, TimeUtils.getCurrentDateFormat() + "Yamato出荷依頼.xls", new ExportParams(), response);
                break;
            case "65":
                final int[] no = new int[1];
                orderOutputDoList.stream().forEach(orderOutputDo -> {
//                                    QueryWrapper wrapper1 = new QueryWrapper();
//                                    wrapper1.eq("order_output_id", orderOutputDo.getId());
//                                    List<OrderOutputPackageDo> packageList = packageDao.selectList(wrapper1);
                    no[0]++;
                    feiyunVoList.addAll(fbaOutputExcelExportFeiyunVo(orderOutputDo, no[0]));
                });
                ExcelUtils.exportExcel(feiyunVoList, FbaOutputExcelExportFeiyunVo.class, TimeUtils.getCurrentDateFormat() + "GreenBox出荷依頼.xls", new ExportParams(), response);
                break;
            case "66":
                orderOutputDoList.stream().forEach(orderOutputDo -> {
                    QueryWrapper wrapper1 = new QueryWrapper();
                    wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
                    List<FbaOrderOutputPackageDo> packageList = packageDao.selectList(wrapper1);
                    seinoExportVoList.add(buildSeinoExportData(orderOutputDo, packageList));
                });
                ExcelUtils.exportExcel(seinoExportVoList, OrderOutputSeinoExportVo.class, TimeUtils.getCurrentDateFormat() + "Seino出荷依頼.xls", new ExportParams(), response);
                break;
            default:
                final int[] packageCount = {0};
                orderOutputDoList.stream().forEach(orderOutputDo -> {
                    StringBuilder stringBuilder = new StringBuilder();
                    QueryWrapper wrapper1 = new QueryWrapper();
                    FbaOrderOutputSelfStorageExportVo exportVo = new FbaOrderOutputSelfStorageExportVo();
                    exportVo.setTips(orderOutputDo.getTips());
                    if (map.get("storageId").equals("9") || map.get("storageId").equals("10")) {
                        exportVo.setStorage(storageDao.selectById(orderOutputDo.getStorageId()).getCode());
                    } else if (map.get("storageId").equals("1")) {
                        exportVo.setStorage("泉2-1-1");
                    } else if (map.get("storageId").equals("11")) {
                        exportVo.setStorage("三ツ堀");
                    }
                    if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
                        FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
                        exportVo.setFbaStorage(fbaStorageDo.getFbaCode());
                    } else {
                        exportVo.setFbaStorage(orderOutputDo.getReceiverName());
                    }
                    exportVo.setCompanyCode(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
                    wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
                    List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper1);
                    List<FbaOrderOutputCommonPackageExportVo> packageExportVoList = new ArrayList<>();
                    int i = 1;
                    for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                        StringBuilder commoditySKu = new StringBuilder();
                        StringBuilder storageSKu = new StringBuilder();
                        int packageSkuCount = 0;
                        StringBuilder skuCount = new StringBuilder();
                        FbaOrderOutputCommonPackageExportVo packageExportVo = new FbaOrderOutputCommonPackageExportVo();
                        BeanUtils.copyProperties(packageDo, packageExportVo);
                        packageExportVo.setPackageCount(packageDo.getCount());
//                                if (packageDo.getCount() == 1) {
//                                    packageExportVo.setPackageNumber(i + "");
//                                } else {
//                                    packageExportVo.setPackageNumber(i + "-" + (i + packageDo.getCount() - 1));
//                                }
//                                i = i + packageDo.getCount();
                        wrapper1 = new QueryWrapper();
                        wrapper1.eq("package_id", packageDo.getId());
                        List<FbaOrderOutputProductDo> productDoList = productDao.selectList(wrapper1);
                        List<FbaOrderOutputCommonProductExportVo> productExcelExportVoList = new ArrayList<>();
                        if (productDoList.size() > 0) {
                            for (FbaOrderOutputProductDo product : productDoList) {
                                FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
                                ProductInfoDo productInfoDo = productInfoDao.selectById(product.getProductId());
                                productExportVo.setCount(product.getCount());
                                if (productInfoDo != null) {
                                    if (commoditySKu.length() > 1) commoditySKu.append(",");
                                    commoditySKu.append(productInfoDo.getCommoditySku());
                                    if (storageSKu.length() > 1) storageSKu.append(",");
                                    storageSKu.append(productInfoDo.getStorageSku());
                                    productExportVo.setCommoditySku(productInfoDo.getCommoditySku());
                                    productExportVo.setStorageSku(productInfoDo.getStorageSku());
                                }
                                packageSkuCount = packageSkuCount + product.getCount() * packageDo.getCount();
                                if (skuCount.length() > 1) skuCount.append(",");
                                skuCount.append(product.getCount());
                                productExcelExportVoList.add(productExportVo);
                            }
                        } else {
                            FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
                            productExcelExportVoList.add(productExportVo);
                        }
                        if (stringBuilder.length() > 1) stringBuilder.append(",");
                        stringBuilder.append(packageDo.getPoNumber());
                        packageExportVo.setProductExportVoList(productExcelExportVoList);
                        packageExportVo.setCommoditySku(commoditySKu.toString());
                        packageExportVo.setStorageSku(storageSKu.toString());
                        packageExportVo.setSkuCount(skuCount.toString());
                        packageExportVo.setTotalCount(packageSkuCount);
                        packageExportVoList.add(packageExportVo);
                        packageCount[0] = packageCount[0] + packageDo.getCount();
                    }
                    exportVo.setPackageExportVoList(packageExportVoList);
//                            exportVo.setPoNumber(stringBuilder.toString());
                    int count = productDao.selectCountByOrderId(orderOutputDo.getId());
                    exportVo.setTotalCount(count);
                    excelExportVoList.add(exportVo);
                });
                FbaOrderOutputSelfStorageExportVo exportVoEnd = new FbaOrderOutputSelfStorageExportVo();
                exportVoEnd.setFbaStorage("合計");
                List<FbaOrderOutputCommonPackageExportVo> packageExportVoListEnd = new ArrayList<>();
                FbaOrderOutputCommonPackageExportVo packageExportVoEnd = new FbaOrderOutputCommonPackageExportVo();
                packageExportVoEnd.setPackageCount(packageCount[0]);
                List<FbaOrderOutputCommonProductExportVo> productExportVoList = new ArrayList<>();
                FbaOrderOutputCommonProductExportVo exportVo = new FbaOrderOutputCommonProductExportVo();
                exportVo.setCommoditySku("");
                exportVo.setStorageSku("");
                productExportVoList.add(exportVo);
                packageExportVoEnd.setProductExportVoList(productExportVoList);
                packageExportVoListEnd.add(packageExportVoEnd);
                exportVoEnd.setPackageExportVoList(packageExportVoListEnd);
                excelExportVoList.add(exportVoEnd);
                ExportParams exportParams = new ExportParams();
                if (map.get("storageId").equals("9") || map.get("storageId").equals("10")) {
                    FbaOrderOutputSelfStorageExportVo exportVoEnd1 = new FbaOrderOutputSelfStorageExportVo();
                    exportVoEnd1.setCompanyCode("拣货人:");
                    exportVoEnd1.setFbaStorage("复核人:");
                    excelExportVoList.add(exportVoEnd1);
                }
                exportParams.setStyle(ExcelExportStylerBorderImpl.class);
                if (map.get("storageId").equals("9") || map.get("storageId").equals("10")) {
                    ExcelUtils.exportExcel(excelExportVoList, FbaOrderOutputSelfStorageExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
                } else {
                    ExcelUtils.exportExcel(excelExportVoList, FbaOrderOutputCommonExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
                }
                //exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response)
                break;
        }
        return null;
    }

//    @Override
//    public SingleResult exportTrackExpress(Map<String, String> map, List<Long> ids, HttpServletResponse response) throws IOException {
//        QueryWrapper<FbaOrderOutputDo> wrapper = queryBuild(map);
//        List<FbaOrderOutputDo> orderOutputDoList;
//        if (ids != null && ids.size() > 0) {
//            orderOutputDoList = this.baseMapper.selectBatchIds(ids);
//        } else {
//            orderOutputDoList = this.baseMapper.selectList(wrapper);
//        }
//        List<FbaOrderOutputCommonPackageExportVo> packageExportVoList = new ArrayList<>();
//        List<FbaOrderOutputSelfStorageExportVo> excelExportVoList = new ArrayList<>();
//        List<OrderOutputSagawaExportVo> sagawaExportVoList = new ArrayList<>();
//        List<FbaOrderOutputSeinoExportVo> seinoExportVoList = new ArrayList<>();
//        List<FbaOutputExcelExportFeiyunVo> feiyunVoList = new ArrayList<>();
//        switch (map.get("trackId")) {
//            case "8":
//                orderOutputDoList.stream()
//                        .sorted(new Comparator<FbaOrderOutputDo>() {
//                            @Override
//                            public int compare(FbaOrderOutputDo o1, FbaOrderOutputDo o2) {
//                                if (o1.getCommoditySku() == null || o2.getCommoditySku() == null) return 1;
//                                return o1.getCommoditySku().compareTo(o2.getCommoditySku());
//                            }
//                        })
//                        .forEach(orderOutputDo -> {
//                            QueryWrapper wrapper1 = new QueryWrapper();
//                            wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
//                            List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper1);
//                            sagawaExportVoList.add(buidSagawaExportData(orderOutputDo, packageDoList));
//                        });
//                CsvExportParams exportParamsS = new CsvExportParams();
//                exportParamsS.setCreateHeadRows(true);
//                exportParamsS.setEncoding("Shift-JIS");
//                CsvUtils.exportCsv(exportParamsS, OrderOutputSagawaExportVo.class, sagawaExportVoList,
//                        TimeUtils.getCurrentDateFormat() + "Sagawa出荷依頼.csv", response);
////                        ExcelUtils.exportExcel(sagawaExportVoList, OrderOutputSagawaExportVo.class, TimeUtils.getCurrentDateFormat() + "Sagawa出荷依頼.xls", new ExportParams(), response);
//                break;
//            case "65":
//                final int[] no = new int[1];
//                orderOutputDoList.stream()
//                        .forEach(orderOutputDo -> {
////                                    QueryWrapper wrapper1 = new QueryWrapper();
////                                    wrapper1.eq("order_output_id", orderOutputDo.getId());
////                                    List<OrderOutputPackageDo> packageList = packageDao.selectList(wrapper1);
//                            no[0]++;
//                            feiyunVoList.addAll(fbaOutputExcelExportFeiyunVo(orderOutputDo, no[0]));
//                        });
//                ExcelUtils.exportExcel(feiyunVoList, FbaOutputExcelExportFeiyunVo.class, TimeUtils.getCurrentDateFormat() + "GreenBox出荷依頼.xls", new ExportParams(), response);
//                break;
//            case "66":
//                orderOutputDoList.stream().forEach(orderOutputDo -> {
//                    QueryWrapper wrapper1 = new QueryWrapper();
//                    wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
//                    List<FbaOrderOutputPackageDo> packageList = packageDao.selectList(wrapper1);
//                    seinoExportVoList.add(buildSeinoExportData(orderOutputDo, packageList));
//                });
//                ExcelUtils.exportExcel(seinoExportVoList, FbaOrderOutputSeinoExportVo.class, TimeUtils.getCurrentDateFormat() + "Seino出荷依頼.xls", new ExportParams(), response);
//                break;
//            default:
//                final int[] packageCount = {0};
//                orderOutputDoList.stream()
//                        .forEach(orderOutputDo -> {
//                            StringBuilder stringBuilder = new StringBuilder();
//                            QueryWrapper wrapper1 = new QueryWrapper();
//                            FbaOrderOutputSelfStorageExportVo exportVo = new FbaOrderOutputSelfStorageExportVo();
//                            exportVo.setTips(orderOutputDo.getTips());
//                            exportVo.setStorage(storageDao.selectById(orderOutputDo.getStorageId()).getCode());
//                            if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
//                                FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
//                                if (fbaStorageDo != null) {
//                                    exportVo.setFbaStorage(fbaStorageDo.getFbaCode());
//                                    exportVo.setCompanyCode(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
//                                }
//                            } else {
//                                exportVo.setFbaStorage(orderOutputDo.getReceiverName());
//                                exportVo.setCompanyCode(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
//                            }
//                            excelExportVoList.add(exportVo);
//                            wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
//                            List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper1);
//
//                            int i = 1;
//                            for (FbaOrderOutputPackageDo packageDo : packageDoList) {
//                                StringBuilder commoditySKu = new StringBuilder();
//                                StringBuilder storageSKu = new StringBuilder();
//                                int packageSkuCount = 0;
//                                StringBuilder skuCount = new StringBuilder();
//                                FbaOrderOutputCommonPackageExportVo packageExportVo = new FbaOrderOutputCommonPackageExportVo();
//                                BeanUtils.copyProperties(packageDo, packageExportVo);
//                                packageExportVo.setPackageCount(packageDo.getCount());
//                                wrapper1 = new QueryWrapper();
//                                wrapper1.eq("package_id", packageDo.getId());
//                                List<FbaOrderOutputProductDo> productDoList = productDao.selectList(wrapper1);
//                                List<FbaOrderOutputCommonProductExportVo> productExcelExportVoList = new ArrayList<>();
//                                if (productDoList.size() > 0) {
//                                    for (FbaOrderOutputProductDo product : productDoList) {
//                                        FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
//                                        ProductInfoDo productInfoDo = productInfoDao.selectById(product.getProductId());
//                                        productExportVo.setCount(product.getCount());
//                                        if (productInfoDo != null) {
//                                            if (commoditySKu.length() > 1)
//                                                commoditySKu.append(",");
//                                            commoditySKu.append(productInfoDo.getCommoditySku());
//                                            if (storageSKu.length() > 1)
//                                                storageSKu.append(",");
//                                            storageSKu.append(productInfoDo.getStorageSku());
//                                            productExportVo.setCommoditySku(productInfoDo.getCommoditySku());
//                                            productExportVo.setStorageSku(productInfoDo.getStorageSku());
//
//                                        }
//                                        packageSkuCount = packageSkuCount + product.getCount() * packageDo.getCount();
//                                        if (skuCount.length() > 1)
//                                            skuCount.append(",");
//                                        skuCount.append(product.getCount());
//                                        productExcelExportVoList.add(productExportVo);
//                                    }
//                                } else {
//                                    FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
//                                    productExcelExportVoList.add(productExportVo);
//                                }
//                                exportVo.setProductExportVoList(productExcelExportVoList);
//
//                                if (stringBuilder.length() > 1)
//                                    stringBuilder.append(",");
//                                stringBuilder.append(packageDo.getPoNumber());
//                                packageExportVo.setProductExportVoList(productExcelExportVoList);
//                                packageExportVo.setCommoditySku(commoditySKu.toString());
//                                packageExportVo.setStorageSku(storageSKu.toString());
//                                packageExportVo.setSkuCount(skuCount.toString());
//
//                                if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
//                                    FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
//                                    if (fbaStorageDo != null) {
//                                        packageExportVo.setFbaStorage(fbaStorageDo.getFbaCode());
//                                    }
//                                } else {
//                                    packageExportVo.setFbaStorage(orderOutputDo.getReceiverName());
//                                }
//                                packageExportVoList.add(packageExportVo);
//                                exportVo.setPoNumber(stringBuilder.toString());
//                                exportVo.setUpcNumber(packageExportVo.getUpcNumber());
//                                exportVo.setPackageCount(packageDo.getCount());
//                                excelExportVoList.add(exportVo);
//
//                                packageCount[0] = packageCount[0] + packageDo.getCount();
//                            }
//                        });
//
//                List<FbaOrderOutputCommonPackageExportVo> packageExportVoListEnd = new ArrayList<>();
//                FbaOrderOutputCommonPackageExportVo packageExportVoEnd = new FbaOrderOutputCommonPackageExportVo();
//                packageExportVoEnd.setFbaStorage("合計");
//                packageExportVoEnd.setPackageCount(packageCount[0]);
//                List<FbaOrderOutputCommonProductExportVo> productExportVoList = new ArrayList<>();
//                productExportVoList.add(new FbaOrderOutputCommonProductExportVo());
//                packageExportVoEnd.setProductExportVoList(productExportVoList);
//                packageExportVoListEnd.add(packageExportVoEnd);
//                packageExportVoList.add(packageExportVoEnd);
//
//                List<FbaOrderOutputSelfStorageExportVo> StorageExportEnd = new ArrayList<>();
//                FbaOrderOutputSelfStorageExportVo exportVoEnd = new FbaOrderOutputSelfStorageExportVo();
//                exportVoEnd.setStorage("合計");
//                exportVoEnd.setPackageCount(packageCount[0]);
//                exportVoEnd.setProductExportVoList(productExportVoList);
//                List<FbaOrderOutputCommonProductExportVo> exportVoList = new ArrayList<>();
//                FbaOrderOutputCommonProductExportVo exportVo = new FbaOrderOutputCommonProductExportVo();
//                exportVoList.add(exportVo);
//                exportVoEnd.setProductExportVoList(exportVoList);
//                excelExportVoList.add(exportVoEnd);
//
//                ExportParams exportParams = new ExportParams("PACKAGE INFO", "PACKAGE INFO");
//                if (StringUtils.isBlank(map.get("storageId"))||Integer.valueOf(map.get("storageId")) >= 9) {
//                    FbaOrderOutputSelfStorageExportVo exportVoEnd1 = new FbaOrderOutputSelfStorageExportVo();
//                    exportVoEnd1.setCompanyCode("拣货人:");
//                    exportVoEnd1.setStorage("复核人:");
//                    List<FbaOrderOutputCommonProductExportVo> productExportVoList1 = new ArrayList<>();
//                    exportVoEnd1.setProductExportVoList(productExportVoList1);
//                    List<FbaOrderOutputCommonProductExportVo> exportVoList1 = new ArrayList<>();
//                    FbaOrderOutputCommonProductExportVo exportVo1 = new FbaOrderOutputCommonProductExportVo();
//                    exportVoList1.add(exportVo1);
//                    exportVoEnd1.setProductExportVoList(exportVoList1);
//                    excelExportVoList.add(exportVoEnd1);
//                }
//                exportParams.setStyle(ExcelExportStylerBorderImpl.class.class);
//                try {
//                    if (StringUtils.isBlank(map.get("storageId"))||Integer.valueOf(map.get("storageId")) >= 9) {
//                        ExcelUtils.exportExcel(excelExportVoList, FbaOrderOutputSelfStorageExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
//                    } else {
//                        ExcelUtils.exportExcel(packageExportVoList, FbaOrderOutputCommonPackageExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
//                    }
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//                //exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response)
//                break;
//        }
//        return null;
//    }

    private List<FbaOutputExcelExportFeiyunVo> fbaOutputExcelExportFeiyunVo(FbaOrderOutputDo orderOutputDo, int no) {
        List<FbaOutputExcelExportFeiyunVo> feiyunVoList = new ArrayList<>();
        LambdaQueryWrapper<FbaOrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
        List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(packageDoList)) {
            for (int i = 0; i < packageDoList.size(); i++) {
                FbaOrderOutputPackageDo orderOutputPackageDo = packageDoList.get(i);
                StringBuilder storageSku = new StringBuilder();
                StringBuilder sku = new StringBuilder();

                FbaOutputExcelExportFeiyunVo feiyunVo = new FbaOutputExcelExportFeiyunVo();
                feiyunVo.setNo(no + "");
                feiyunVo.setPackageId(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode() + "-" + orderOutputDo.getOrderNo() + (i < 1 ? "" : ("-" + i)));
                feiyunVo.setHei(orderOutputPackageDo.getHeight());
                feiyunVo.setLen(orderOutputPackageDo.getLength());
                feiyunVo.setWei(orderOutputPackageDo.getWeight());
                feiyunVo.setWith(orderOutputPackageDo.getWidth());
                feiyunVo.setPackageCount(orderOutputPackageDo.getCount());
//                feiyunVo.setPoNumber(orderOutputDo.getPoNumber());
                feiyunVo.setSanBian(orderOutputPackageDo.getHeight() + orderOutputPackageDo.getLength() + orderOutputPackageDo.getWidth());
                feiyunVo.setPackageCount(orderOutputPackageDo.getCount());
                if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
                    FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
                    if (fbaStorageDo != null) {
                        feiyunVo.setFbaName(fbaStorageDo.getFbaName());
                        feiyunVo.setFbaCode(fbaStorageDo.getFbaCode());
                    }
                } else {
                    ShippingAddressDo fbaStorageDo = shippingAddressDao.selectById(orderOutputDo.getFbaStorageId());
                    if (fbaStorageDo != null) {
                        feiyunVo.setFbaName(fbaStorageDo.getCompanyName());
                        feiyunVo.setFbaCode(fbaStorageDo.getCompanyName());
                    } else {
                        feiyunVo.setFbaName(orderOutputDo.getReceiverName());
                        feiyunVo.setFbaCode(orderOutputDo.getReceiverName());
                    }
                }
                int packageSkuCount = 0;
                int skuCount = 0;

                LambdaQueryWrapper<FbaOrderOutputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                productDoLambdaQueryWrapper.eq(FbaOrderOutputProductDo::getPackageId, orderOutputPackageDo.getId());
                List<FbaOrderOutputProductDo> orderOutputProductDoList = productDao.selectList(productDoLambdaQueryWrapper);
                if (!CollectionUtils.isEmpty(orderOutputProductDoList)) {
                    for (FbaOrderOutputProductDo orderOutputProductDo : orderOutputProductDoList) {
                        packageSkuCount += orderOutputPackageDo.getCount() * orderOutputProductDo.getCount();
                        skuCount += orderOutputProductDo.getCount();
                        ProductInfoDo productInfoDo = productInfoDao.selectById(orderOutputProductDo.getProductId());
                        if (productInfoDo != null) {
                            if (storageSku.length() > 0) storageSku.append(",");
                            storageSku.append(productInfoDo.getStorageSku());
                            if (sku.length() > 0) sku.append(",");
                            sku.append(productInfoDo.getCommoditySku());
                        }
                    }
                }
                feiyunVo.setPackageSkuCount(packageSkuCount);
                feiyunVo.setSkuCount(skuCount);
                feiyunVo.setStorageSku(storageSku.toString());
                feiyunVo.setCommoditySku(sku.toString());
                feiyunVo.setPoNumber(orderOutputPackageDo.getPoNumber());
                feiyunVoList.add(feiyunVo);
            }
        }
        return feiyunVoList;
    }


    private OrderOutputSagawaExportVo buidSagawaExportData(FbaOrderOutputDo orderOutputDo, List<FbaOrderOutputPackageDo> packageDoList) {
        OrderOutputSagawaExportVo exportVo = new OrderOutputSagawaExportVo();
        if (orderOutputDo.getStorageId() == 10 || orderOutputDo.getStorageId() == 11 || orderOutputDo.getStorageId() == 1) {
            exportVo.setE3("146671890004");
            exportVo.setE5("0471-36-1830");
            exportVo.setE6("0471-36-1830");
            exportVo.setE7("278-0002");
            exportVo.setE8("千葉県野田市木野崎字");
            exportVo.setE9("鹿野1788番地２-1");
        } else if (orderOutputDo.getStorageId() == 12) {
            exportVo.setE3("");
            exportVo.setE5("0471361830");
            exportVo.setE6("0471361830");
            exportVo.setE7("596-0015");
            exportVo.setE8("大阪府岸和田市");
            exportVo.setE9("地蔵浜町１１−２");
            exportVo.setE10("株式会社　ロンコ・ジャパン");
//        }else if (orderOutputDo.getCompanyId().intValue() == 221) {
//            exportVo.setE10("Tell Way Energy Group Ltd.,　様");
//            exportVo.setE6("048-299-9264");
//            exportVo.setE7("3330866");
//            exportVo.setE8("埼玉県川口市芝1丁目");
        }
        FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
        if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS) && fbaStorageDo != null) {
            orderOutputDo.setTelPhone(fbaStorageDo.getTelPhone());
            orderOutputDo.setPostCode(fbaStorageDo.getPostCode());
            orderOutputDo.setAddress(fbaStorageDo.getAddress());
            if (fbaStorageDo.getFbaCode().startsWith("RFC")) {
                orderOutputDo.setReceiverName(fbaStorageDo.getFbaCode() + "入庫係");
            } else if (fbaStorageDo.getFbaCode().startsWith("其他")) {
                orderOutputDo.setTelPhone(orderOutputDo.getTelPhone());
                orderOutputDo.setPostCode(orderOutputDo.getPostCode());
                orderOutputDo.setAddress(orderOutputDo.getAddress());
                orderOutputDo.setReceiverName(orderOutputDo.getReceiverName());
            } else {
                orderOutputDo.setReceiverName("Amazon.co.jp   " + fbaStorageDo.getFbaCode() + " FBA入庫係");
            }
        } else {
            orderOutputDo.setTelPhone(orderOutputDo.getTelPhone());
            orderOutputDo.setPostCode(orderOutputDo.getPostCode());
            orderOutputDo.setAddress(orderOutputDo.getAddress());
            orderOutputDo.setReceiverName(orderOutputDo.getReceiverName());
        }
        if (StringUtils.isNotBlank(orderOutputDo.getTelPhone()))
            exportVo.setTelPhone(orderOutputDo.getTelPhone().replaceAll("\\n", ""));
        exportVo.setPostCode(orderOutputDo.getPostCode().replaceAll("-", "").replaceAll("\\n", ""));
        orderOutputDo.setAddress(orderOutputDo.getAddress().replaceAll("\\n", ""));
        if (orderOutputDo.getAddress().length() <= 15) {
            exportVo.setAddress1(orderOutputDo.getAddress());
        } else if (orderOutputDo.getAddress().length() > 15 && orderOutputDo.getAddress().length() <= 30) {
            exportVo.setAddress1(orderOutputDo.getAddress().substring(0, 15));
            exportVo.setAddress2(orderOutputDo.getAddress().substring(15));
        } else {
            exportVo.setAddress1(orderOutputDo.getAddress().substring(0, 15));
            exportVo.setAddress2(orderOutputDo.getAddress().substring(15, 30));
            exportVo.setAddress3(orderOutputDo.getAddress().substring(30));
        }
        if (StringUtils.isNotBlank(orderOutputDo.getReceiverName())) {
            orderOutputDo.setReceiverName(orderOutputDo.getReceiverName().replaceAll("\\n", ""));
            if (orderOutputDo.getReceiverName().length() <= 15) {
                exportVo.setReceiverName(orderOutputDo.getReceiverName());
            } else {
                exportVo.setReceiverName(orderOutputDo.getReceiverName().substring(0, 15));
                exportVo.setReceiverName2(orderOutputDo.getReceiverName().substring(15));
            }
        }
        int packageCount = 0;
        if (packageDoList != null && packageDoList.size() > 0) {
            StringBuilder sku = new StringBuilder();
            for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                LambdaQueryWrapper<FbaOrderOutputProductDo> wrapper = new LambdaQueryWrapper();
                wrapper.eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId());
                List<FbaOrderOutputProductDo> productDoList = productDao.selectList(wrapper);
                if (packageDoList.size() == 1) {
                    if (productDoList != null && productDoList.size() > 0) {
                        ProductInfoDo productInfoDo = productInfoDao.selectById(productDoList.get(0).getProductId());
                        if (productInfoDo != null)
                            sku.append(productInfoDo.getCommoditySku() + (productDoList.size() == 1 ? ("* " + productDoList.get(0).getCount() * packageDo.getCount()) : "など"));
                    } else {
                        sku.append("など");
                    }
                }
                packageCount += packageDo.getCount();
            }
            exportVo.setCommoditySku(sku.toString());
        }
        exportVo.setOrderNumber(orderOutputDo.getFbaOrderOutputNumber());
        exportVo.setStorageSku(orderOutputDo.getOrderNo());
        exportVo.setStorageSku1(orderOutputDo.getPoNumber());
        if (orderOutputDo.getDeliveryDate() != null)
            exportVo.setDeliveryDate(TimeUtils.formatDate(orderOutputDo.getDeliveryDate(), "yyyyMMdd"));

        exportVo.setCount(packageCount + "");
        return exportVo;

    }

    private OrderOutputYamatoExportVo buildYamatoExportData(FbaOrderOutputDo orderOutputDo, FbaOrderOutputPackageDo
            orderInputPackageDo, int i) {
        OrderOutputYamatoExportVo exportVo = new OrderOutputYamatoExportVo();
        if (orderOutputDo.getStorageId() == 10 || orderOutputDo.getStorageId() == 11 || orderOutputDo.getStorageId() == 1) {
            exportVo.setE9("筋斗雲株式会社");
        } else if (orderOutputDo.getStorageId() == 12) {
            exportVo.setE10("筋斗雲株式会社");
//        }else if (orderOutputDo.getCompanyId().intValue() == 221) {
//            exportVo.setE10("Tell Way Energy Group Ltd.,　様");
//            exportVo.setE6("048-299-9264");
//            exportVo.setE7("3330866");
//            exportVo.setE8("埼玉県川口市芝1丁目");
        }
        exportVo.setSendDate(TimeUtils.formatDate(new Date(), "yyy/MM/dd"));

        FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
        if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS) && fbaStorageDo != null) {
            orderOutputDo.setTelPhone(fbaStorageDo.getTelPhone());
            orderOutputDo.setPostCode(fbaStorageDo.getPostCode());
            orderOutputDo.setAddress(fbaStorageDo.getAddress());
            if (fbaStorageDo.getFbaCode().startsWith("RFC")) {
                orderOutputDo.setReceiverName(fbaStorageDo.getFbaCode() + "入庫係");
            } else if (fbaStorageDo.getFbaCode().startsWith("其他")) {
                orderOutputDo.setTelPhone(orderOutputDo.getTelPhone());
                orderOutputDo.setPostCode(orderOutputDo.getPostCode());
                orderOutputDo.setAddress(orderOutputDo.getAddress());
                orderOutputDo.setReceiverName(orderOutputDo.getReceiverName());
            } else {
                orderOutputDo.setReceiverName("Amazon.co.jp   " + fbaStorageDo.getFbaCode() + " FBA入庫係");
            }
        } else {
            orderOutputDo.setTelPhone(orderOutputDo.getTelPhone());
            orderOutputDo.setPostCode(orderOutputDo.getPostCode());
            orderOutputDo.setAddress(orderOutputDo.getAddress());
            orderOutputDo.setReceiverName(orderOutputDo.getReceiverName());
        }
        orderOutputDo.setAddress(orderOutputDo.getAddress().trim().replaceAll("\\n", "").replaceAll("　", " ").replaceAll("－", "-").replaceAll("−", "-").replaceAll("－", "-"));
        if (orderOutputDo.getAddress().length() <= 22) {
            exportVo.setAddress1(orderOutputDo.getAddress());
        } else if (orderOutputDo.getAddress().length() <= 37) {
            exportVo.setAddress1(orderOutputDo.getAddress().substring(0, 22));
            exportVo.setAddress2(orderOutputDo.getAddress().substring(22));
        } else if (orderOutputDo.getAddress().length() <= 60) {
            exportVo.setAddress1(orderOutputDo.getAddress().substring(0, 22));
            exportVo.setAddress2(orderOutputDo.getAddress().substring(22, 37));
            exportVo.setE3(orderOutputDo.getAddress().substring(37));
        } else {
            exportVo.setAddress1(orderOutputDo.getAddress().substring(0, 22));
            exportVo.setAddress2(orderOutputDo.getAddress().substring(22, 37));
            exportVo.setE3(orderOutputDo.getAddress().substring(37, 60));
            exportVo.setE4(orderOutputDo.getAddress().substring(60));
        }
        if (StringUtils.isNotBlank(orderOutputDo.getTelPhone())) {
//            exportVo.setManagerNo(orderOutputDo.getTelPhone().replaceAll("\\+81", ""));
            exportVo.setE2(orderOutputDo.getTelPhone());
            exportVo.setReceiverTelPhone(orderOutputDo.getTelPhone().replaceAll("－", "").replaceAll("-", ""));
        }
        if (StringUtils.isNotBlank(exportVo.getReceiverTelPhone()) && exportVo.getReceiverTelPhone().startsWith("81")) {
            exportVo.setReceiverTelPhone(exportVo.getReceiverTelPhone().replaceFirst("81", ""));
        }
        exportVo.setReceiverName(orderOutputDo.getReceiverName());
        exportVo.setPostCode(orderOutputDo.getPostCode().replaceAll("-", ""));
        if (i < 1) {
            exportVo.setOrderNo(orderOutputDo.getFbaOrderOutputNumber());
        } else {
            exportVo.setOrderNo(orderOutputDo.getFbaOrderOutputNumber() + "-" + i);
        }
        if (orderOutputDo.getDeliveryDate() != null)
            if (orderOutputDo.getDeliveryDate().getTime() < System.currentTimeMillis()) {
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.DAY_OF_YEAR, 1);
                exportVo.setDeliveryDate(TimeUtils.formatDate(calendar.getTime(), "yyyy/MM/dd"));
            } else {
                exportVo.setDeliveryDate(TimeUtils.formatDate(orderOutputDo.getDeliveryDate(), "yyyy/MM/dd"));
            }
        int packageCount = 0;
        StringBuilder sku = new StringBuilder();
        StringBuilder storageSku = new StringBuilder();
        LambdaQueryWrapper<FbaOrderOutputProductDo> wrapper = new LambdaQueryWrapper();
        wrapper.eq(FbaOrderOutputProductDo::getPackageId, orderInputPackageDo.getId());
        List<FbaOrderOutputProductDo> productDoList = productDao.selectList(wrapper);
        if (productDoList != null && productDoList.size() > 0) {
            ProductInfoDo productInfoDo = productInfoDao.selectById(productDoList.get(0).getProductId());
            if (productInfoDo != null)
                sku.append(productInfoDo.getCommoditySku() +
                        (productDoList.size() == 1 ? ("* " + productDoList.get(0).getCount()) : "など"));
            storageSku.append(productInfoDo.getStorageSku() +
                    (productDoList.size() == 1 ? ("* " + productDoList.get(0).getCount()) : "など"));
        } else {
            sku.append("など");
        }
        exportVo.setCommoditySku(sku.toString());
        exportVo.setStorageSku(storageSku.toString());
        exportVo.setE18("3");//是否显示序号
        exportVo.setCount(orderInputPackageDo.getCount() + "");

        return exportVo;

    }

    private FbaOrderOutputSeinoExportVo buildSeinoExportData(FbaOrderOutputDo
                                                                     orderOutputDo, List<FbaOrderOutputPackageDo> packageDoList) {
        FbaOrderOutputSeinoExportVo exportVo = new FbaOrderOutputSeinoExportVo();
        exportVo.setSendDate(TimeUtils.formatDate(orderOutputDo.getSendDate(), "yyy/MM/dd"));
        exportVo.setManagerNo(orderOutputDo.getTelPhone());
        exportVo.setE2(orderOutputDo.getTelPhone());
        exportVo.setReceiverTelPhone(orderOutputDo.getTelPhone());
        exportVo.setReceiverName(orderOutputDo.getReceiverName());
        exportVo.setPostCode(orderOutputDo.getPostCode().replaceAll("-", ""));
        orderOutputDo.setAddress((orderOutputDo.getArea() == null ? "" : orderOutputDo.getArea()) + orderOutputDo.getAddress().trim());
        if (orderOutputDo.getAddress().length() <= 15) {
            exportVo.setAddress1(orderOutputDo.getAddress());
        } else {
            exportVo.setAddress1(orderOutputDo.getAddress().substring(0, 15));
            exportVo.setAddress2(orderOutputDo.getAddress().substring(15));
        }
        if (orderOutputDo.getStorageId() == 10 || orderOutputDo.getStorageId() == 11 || orderOutputDo.getStorageId() == 1) {
            exportVo.setE6("0471-36-1830");
            exportVo.setE7("0471-36-1830");
            exportVo.setE10("278-0002");
            exportVo.setE11("千葉県野田市木野崎字鹿野1788番地２-1");
        }
//        exportVo.setReceiverName(orderOutputDo.getReceiverName());
        FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
        if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS) && fbaStorageDo != null) {
            exportVo.setReceiverName("Amazon.co.jp " + fbaStorageDo.getFbaCode() + " FBA入庫係");
        } else {
            exportVo.setReceiverName(orderOutputDo.getReceiverName());
        }
        int packageCount = 0;
        StringBuilder sku = new StringBuilder();
        for (FbaOrderOutputPackageDo packageDo : packageDoList) {
            LambdaQueryWrapper<FbaOrderOutputProductDo> wrapper = new LambdaQueryWrapper();
            wrapper.eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId());
            List<FbaOrderOutputProductDo> productDoList = productDao.selectList(wrapper);
            if (packageDoList.size() == 1) {
                if (productDoList != null && productDoList.size() > 0) {
                    ProductInfoDo productInfoDo = productInfoDao.selectById(productDoList.get(0).getProductId());
                    if (productInfoDo != null)
                        sku.append(productInfoDo.getCommoditySku() + (productDoList.size() == 1 ? ("* " + productDoList.get(0).getCount() * packageDo.getCount()) : "など"));
                } else {
                    sku.append("など");
                }
            }
            packageCount += packageDo.getCount();
        }
        exportVo.setCommoditySku(sku.toString());
        exportVo.setOrderNo(orderOutputDo.getFbaOrderOutputNumber());
        exportVo.setStorageSku(orderOutputDo.getOrderNo());
        if (orderOutputDo.getDeliveryDate() != null)
            exportVo.setDeliveryDate(TimeUtils.formatDate(orderOutputDo.getDeliveryDate(), "yyyy/MM/dd"));
        exportVo.setDeliveryTimeCode(TimeUtils.getYamatoDTime(orderOutputDo.getDeliveryTime()));
        if (orderOutputDo.getCod() != 0 && orderOutputDo.getCod() != 0) {
            exportVo.setExpressNo("2");
            exportVo.setTaxFee("0");
            exportVo.setCod(orderOutputDo.getCod() + "");
        }
        exportVo.setCount(packageCount + "");
        return exportVo;

    }

    private void sufficientFundsCheck(Long companyId) {
        if (!companyAccountService.getIsDue(companyId)) {
            throw new NotSufficientFundsException(ErrorEnum.NOT_SUFFICIENT_FUNDS);
        } else if (false) {
            throw new NotSufficientFundsException(ErrorEnum.NOT_SUFFICIENT_FUNDS);

        }
    }

    @Override
    public SingleResult updateFbaStatusInit(Long orderId, Long currentUserId) {
        FbaOrderOutputDo et = dao.selectById(orderId);
        if (et == null) {
            throw new BizException(SysConstant.Order_NotExist);
        }

        List<Map> list = new ArrayList<>();
        LambdaQueryWrapper<DicBusinessItemDo> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.fbaOrderOutputStatus);
        for (DicBusinessItemDo itemDo : dicBusinessItemDao.selectList(wrapper1)) {
            Map map1 = new HashMap();

            map1.put("id", itemDo.getId());
            map1.put("value", itemDo.getDicItemValue());

            if (itemDo.getId().equals(et.getStatus())) {
                list.add(map1);
                continue;
            }
            if (et.getStatus().equals(DicBusinessItemConstant.fbaInCreateState)) {
                //已下单 只能改成已审核
                if (itemDo.getId().equals(DicBusinessItemConstant.fbaOrderCheckStatus)) {
                    list.add(map1);
                    break;
                }
            } else if (et.getStatus().equals(DicBusinessItemConstant.fbaOrderCheckStatus) || et.getStatus().equals(DicBusinessItemConstant.fbaOrderPrintStatus) || et.getStatus().equals(DicBusinessItemConstant.fbaOrderAppointStorageStatus) || et.getStatus().equals(DicBusinessItemConstant.fbaOrderAppointCarStatus)) {
                //已审核 可以改成 已打单 约仓 约车
                if (itemDo.getId().equals(DicBusinessItemConstant.fbaOrderCheckStatus) || itemDo.getId().equals(DicBusinessItemConstant.fbaOrderPrintStatus) || itemDo.getId().equals(DicBusinessItemConstant.fbaOrderAppointStorageStatus) || itemDo.getId().equals(DicBusinessItemConstant.fbaOrderAppointCarStatus)) {
                    list.add(map1);
                }
            } else if (et.getStatus().equals(DicBusinessItemConstant.fbaOrderSendOutStatus) || et.getStatus().equals(DicBusinessItemConstant.fbaOrderSignStatus)) {
                if (itemDo.getId().equals(DicBusinessItemConstant.fbaOrderCheckStatus)) {
                    list.add(map1);
                }
            }

        }
        SingleResult singleResult = SingleResult.success();
        singleResult.setData(list);

        CompanyDo companyDo = companyDao.selectById(et.getCompanyId());
        if (companyDo != null) {
            CompanyAccountDo accountDo = companyAccountService.getOne(new LambdaQueryWrapper<CompanyAccountDo>().eq(CompanyAccountDo::getCompanyId, companyDo.getId()));
            if (accountDo != null && accountDo.getCompanyAccount() < 0) {
                Map mapInfo = new HashMap();
                mapInfo.put("companyAccount", accountDo.getCompanyAccount());
                singleResult.setMapInfo(mapInfo);

            }
        }

        return singleResult;
    }

    @Override
    public boolean updateFbaStatus(String id, String status, String sysTips, Long currentUserId) {
        FbaOrderOutputDo orderOutputDo = dao.selectById(id);
        return updateFbaStatus(orderOutputDo, status, sysTips, currentUserId);
    }

    public boolean updateFbaStatus(FbaOrderOutputDo orderOutputDo, String status, String sysTips, Long
            currentUserId) {
        if (orderOutputDo == null) {
            throw new BizException(SysConstant.Order_Detail_Notfound);
        }
        if (StringUtils.isNotBlank(sysTips)) {
            orderOutputDo.setSysTips(sysTips);
        }

        boolean roll = false;
        if ((orderOutputDo.getStatus().equals(DicBusinessItemConstant.fbaOrderSendOutStatus) || orderOutputDo.getStatus().equals(DicBusinessItemConstant.fbaOrderSignStatus)) && Long.parseLong(status) < DicBusinessItemConstant.fbaOrderSendOutStatus) {
            roll = true;
            //已签收 已发货回滚
            dealwithOrderOutBack(orderOutputDo, orderOutputDo.getTrackId());

            Map<Long, Integer> countMap = new HashMap<>();
            LambdaQueryWrapper<FbaOrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, orderOutputDo.getId());
            List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
            for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                List<FbaOrderOutputProductDo> productList = productDao.selectList(new QueryWrapper<FbaOrderOutputProductDo>().eq("package_id", packageDo.getId()));
                for (FbaOrderOutputProductDo pt : productList) {
                    countMap.merge(pt.getProductId(), pt.getCount() * packageDo.getCount(), Integer::sum);
                }
            }

            List<ProductStockFlowingDo> flowingDoList = productStockFlowingDao.selectList(new LambdaQueryWrapper<ProductStockFlowingDo>().eq(ProductStockFlowingDo::getType, StaticDict.Product_Flowing_Type.FbaSend.getValue()).eq(ProductStockFlowingDo::getNoteNo, orderOutputDo.getFbaOrderOutputNumber()));
            Map<Long, List<ProductStockFlowingDo>> flowingMapList = flowingDoList.stream().collect(Collectors.groupingBy(ProductStockFlowingDo::getProductId));

            for (Long productId : countMap.keySet()) {
//                ProductOutDo productOutDo = productOutService.getOne(new LambdaQueryWrapper<ProductOutDo>()
//                        .eq(ProductOutDo::getOutNo, orderOutputDo.getFbaOrderOutputNumber()).eq(ProductOutDo::getProductId, productId)
//                        .eq(ProductOutDo::getShopId, orderOutputDo.getShopId()).eq(ProductOutDo::getStorageId, orderOutputDo.getStorageId()));
//                if (productOutDo == null) {
//                    throw new BizException("出库记录未匹配");
//                }

                List<ProductStockFlowingDo> flowList = flowingMapList.get(productId);
                if (flowList.size() == 0) {
                    throw new BizException(SysConstant.Product_Flowing_NotMatch);
                }
                if (orderOutputDo.getPickUpId() != null && !orderOutputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.ToPick.getValue())) {
                    //待拣货 已拣货
                    if (flowList.stream().mapToInt(ProductStockFlowingDo::getGoodLockingQuantity).sum() != -countMap.get(productId)) {
                        throw new BizException(SysConstant.Product_Flowing_NotMatch);
                    }
                } else {
                    if (flowList.stream().mapToInt(ProductStockFlowingDo::getGoodQuantity).sum() != -countMap.get(productId)) {
                        throw new BizException(SysConstant.Product_Flowing_NotMatch);
                    }
                }

                for (ProductStockFlowingDo flowingDo : flowList) {
//                    if (flowingDo == null) {
//                        throw new BizException(SysConstant.Product_Flowing_NotMatch);
//                    }
                    //去匹配 出库单出库的哪条库存
                    ProductStockDo stockDo = new ProductStockDo();
                    stockDo.setProductId(productId);
                    stockDo.setStorageId(flowingDo.getStorageId());
                    if (orderOutputDo.getPickUpId() != null && !orderOutputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.ToPick.getValue())) {
                        //锁定了库存
                        stockDo.setReceiveQuantity(-flowingDo.getGoodLockingQuantity());
                        stockDo.setReceiveGoodQuantity(-flowingDo.getGoodLockingQuantity());
                        stockDo.setGoodQuantity(-flowingDo.getGoodLockingQuantity());
                    } else {
                        stockDo.setReceiveQuantity(-flowingDo.getGoodQuantity());
                        stockDo.setReceiveGoodQuantity(-flowingDo.getGoodQuantity());
                        stockDo.setGoodQuantity(-flowingDo.getGoodQuantity());
                    }
                    stockDo.setOrderType("fbaOutputRoll");
                    stockDo.setCreateTime(new Date());
                    stockDo.setCreateBy(currentUserId);
                    stockDo.setCompanyId(flowingDo.getCompanyId());
//                stockDo.setShopId(flowingDo.getShopId());
                    productStockDao.insert(stockDo);

                    ProductStockRackDo stockRackDo = new ProductStockRackDo();
                    stockRackDo.setStockId(stockDo.getId());
                    stockRackDo.setRackId(flowingDo.getRackId());
                    stockRackDo.setGoodQuantity(stockDo.getGoodQuantity());
                    stockRackDo.setBadQuantity(0);
                    stockRackDo.setCreateTime(new Date());
                    productStockRackDao.insert(stockRackDo);

                    productStockFlowingService.insertFlowing(StaticDict.Product_Flowing_Type.FbaOutputRoll.getValue(), flowingDo.getNoteNo(), flowingDo.getShopId(), flowingDo.getProductId(), flowingDo.getStorageId(), stockDo.getGoodQuantity(), 0, 0, flowingDo.getRackId(), flowingDo.getCompanyId(), currentUserId, "Fba出库单 回滚");
                }
            }

        }
        orderOutputDo.setStatus(Long.parseLong(status));
        orderOutputDo.setUpdateTime(new Date());
        orderOutputDo.setUpdateBy(currentUserId);
        DicBusinessItemDo itemDo = dicBusinessItemDao.selectById(status);
        if (itemDo != null) {
            operateRecordDao.operateAddRecord(SysConstant.OPERATE_UPDATE_FBA_ORDER_STATUS, orderOutputDo.getId(), orderOutputDo.getUpdateBy(), 6);
//            operateRecord(itemDo.getDicItemValue() + "更新", orderOutputDo.getId(), currentUserId);
        }
        boolean result = updateById(orderOutputDo);

        if (roll) {
            LambdaUpdateWrapper<FbaOrderOutputDo> update = new LambdaUpdateWrapper<FbaOrderOutputDo>();
            update.eq(FbaOrderOutputDo::getId, orderOutputDo.getId());
            update.set(FbaOrderOutputDo::getPickUpId, null);
            update.set(FbaOrderOutputDo::getPickStatus, StaticDict.Pick_Up_Status.ToPick.getValue());
            this.update(update);

            //判断拣货单
            stockPickUpService.deletePickUp(orderOutputDo.getPickUpId(), orderOutputDo.getId());
            //删除fbaSend 发货记录
            productStockFlowingDao.delete(new LambdaQueryWrapper<ProductStockFlowingDo>().eq(ProductStockFlowingDo::getType, StaticDict.Product_Flowing_Type.FbaSend.getValue()).eq(ProductStockFlowingDo::getCompanyId, orderOutputDo.getCompanyId()).eq(ProductStockFlowingDo::getNoteNo, orderOutputDo.getFbaOrderOutputNumber()));
        }

        return result;
    }

    @Override
    public List<FbaExcelImportPackageRes> importExcel(MultipartFile file, Long storageId, Long shopId, Long
            companyId) throws IOException {
        if (storageId == null) {
            throw new BizException(SysConstant.Pls_Choose_Storage);
        }
        if (shopId == null) {
            throw new BindException(SysConstant.Pls_Choose_Shop);
        }
        if (file == null) throw new BizException(SysConstant.Pls_Choose_File);
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if (!GlobalConstants.IMG_TYPE_XLS.equals(suffix.toUpperCase()) && !GlobalConstants.IMG_TYPE_XLSX.equals(suffix.toUpperCase())) {
            throw new BizException(SysConstant.File_Form_Incorrect);
        }
        List<FBaExcelImportVo> excelImportVoList = ExcelUtils.importExcel(file, 0, 1, FBaExcelImportVo.class);
        List<FbaExcelImportPackageRes> packageList = new ArrayList<>();
        Map<Long, List<FBaExcelImportVo>> map = excelImportVoList.stream().filter(product -> product.getPackageCount() != null && product.getLength() != null && product.getWidth() != null).collect(Collectors.groupingBy(FBaExcelImportVo::getPackageNo));
        if (!CollectionUtils.isEmpty(map)) {
            //获取库存
            Map<String, String> param = new HashMap();
            param.put("storageId", storageId + "");
            param.put("shopId", shopId + "");
            List<StockRecordPageRes> stockList = stockRecordService.getList(param);
            Map<Long, List<StockRecordPageRes>> stockListMap = stockList.stream().collect(Collectors.groupingBy(StockRecordPageRes::getProductInfoId));

            for (Long packageNo : map.keySet()) {
                List<FBaExcelImportVo> excelImportVos = map.get(packageNo);
                if (!CollectionUtils.isEmpty(excelImportVos)) {
                    FbaExcelImportPackageRes packageAdd = new FbaExcelImportPackageRes();
                    packageAdd.setPackageHeight(excelImportVos.get(0).getHeight().floatValue());
                    packageAdd.setPackageLenght(excelImportVos.get(0).getLength().floatValue());
                    packageAdd.setPackageWidth(excelImportVos.get(0).getWidth().floatValue());
                    packageAdd.setPackageWeight(excelImportVos.get(0).getWeight().floatValue());
                    packageAdd.setPackageCount(excelImportVos.get(0).getPackageCount());
                    packageAdd.setPoNumber(excelImportVos.get(0).getPoNumber());
                    packageAdd.setUpcNumber(excelImportVos.get(0).getUpcNumber());
                    packageAdd.setTips(excelImportVos.get(0).getTips());

                    List<JSONObject> productAddList = new ArrayList<>();
                    for (FBaExcelImportVo excelImportVo : excelImportVos) {
                        //商品
                        if (StringUtils.isBlank(excelImportVo.getCommoditySku())) continue;
                        JSONObject productAdd = new JSONObject();
                        LambdaQueryWrapper<ProductInfoDo> wrapper = new LambdaQueryWrapper<>();
                        wrapper.or(productWrapper -> {
                            productWrapper.eq(ProductInfoDo::getCommoditySku, excelImportVo.getCommoditySku()).or().eq(ProductInfoDo::getStorageSku, excelImportVo.getCommoditySku());
                        });
                        if (companyId != null && companyId != 0L)
                            wrapper.eq(ProductInfoDo::getCompanyId, companyId);
                        ProductInfoDo productInfoDo = productInfoDao.selectOne(wrapper);
                        if (productInfoDo != null) {
                            productAdd.put("productId", productInfoDo.getId());
                            productAdd.put("commoditySku", productInfoDo.getCommoditySku());
                            productAdd.put("productName", productInfoDo.getCommodityName());
//                            productAdd.put("createTime", productInfoDo.getCreateTime());
                            if (stockListMap.get(productInfoDo.getId()) != null) {
                                productAdd.put("canSellCount", stockListMap.get(productInfoDo.getId()).get(0).getCanSellCount() - stockListMap.get(productInfoDo.getId()).get(0).getNoDelivered());
                                productAdd.put("createTime", stockListMap.get(productInfoDo.getId()).get(0).getUpdateTime());
                            } else {
                                productAdd.put("canSellCount", 0);
                            }
                        } else {
                            productAdd.put("productId", "");
                            productAdd.put("commoditySku", "产品不存在，请检查SKU");
                            productAdd.put("productName", "");
                            productAdd.put("createTime", "");
                            productAdd.put("canSellCount", 0);
                        }
                        productAdd.put("count", excelImportVo.getCount());

                        productAddList.add(productAdd);
                    }

                    packageAdd.setProductDetailList(productAddList);

                    packageList.add(packageAdd);
                }
            }
        }

        return packageList;
    }

    @Override
    public SingleResult updateTrackNumber(FbaOrderOutputUpdateTrackNumberReq req, Long userId) {
        FbaOrderOutputDo orderOutputDo = dao.selectById(req.getId());
        if (orderOutputDo == null) throw new BizException(SysConstant.Order_NotExist);
        orderOutputDo.setTrackId(req.getTrackId());
        orderOutputDo.setUpdateTime(new Date());
        orderOutputDo.setUpdateBy(userId);
        if (StringUtils.isNotBlank(req.getTrackNumber()) && !req.getTrackNumber().equals(orderOutputDo.getTrackNumber())) {
            orderOutputDo.setTrackNumber(req.getTrackNumber());
            Long oldStatus = orderOutputDo.getStatus();
            if (orderOutputDo.getStatus().equals(DicBusinessItemConstant.fbaOrderPrintStatus) || orderOutputDo.getStatus().equals(DicBusinessItemConstant.fbaOrderAppointStorageStatus) || orderOutputDo.getStatus().equals(DicBusinessItemConstant.fbaOrderAppointCarStatus)) {
                //未关联拣货单 由前端给推荐库位
                if (orderOutputDo.getPickUpId() == null) {
                    if (req.getPositionAndNumberList() == null || req.getPositionAndNumberList().size() == 0) {
                        throw new BizException(SysConstant.Order_StockRack_Null);
                    }
                    this.dealwithOrderSendOut(orderOutputDo, req.getTrackId(), userId);
                    this.sendWhenOutWaitSendOut(req.getPositionAndNumberList(), orderOutputDo, oldStatus, userId, false);//未拣货
                }
                //关联拣货单 但是 未完成拣货
//                else if (orderOutputDo.getPickUpId() != null && orderOutputDo.getPickUpId() != 0 && orderOutputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.UnPick.getValue())) {
//                    //先去完成拣货
//                    StockPickUpDo pickUpDo = stockPickUpDao.selectById(orderOutputDo.getPickUpId());
//                    if (pickUpDo == null) {
//                        throw new BizException(SysConstant.FbaOrder_Pickup_NotMatch);
//                    }
//                    stockPickUpService.finishPickUp(pickUpDo, new HashSet<>(), userId, orderOutputDo.getId());
//                    //再去正常出库，此时拣货单已拣货
//                    this.dealwithOrderSendOut(orderOutputDo, req.getTrackId(), userId);
//                }
                //已拣货 或者待拣货 都已锁定库存，直接发货
                else if (orderOutputDo.getPickUpId() != null && orderOutputDo.getPickUpId() != 0 && !orderOutputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.ToPick.getValue())) {
                    //操作旧表库存， 并且如果已拣货 顺便操作新表
                    this.dealwithOrderSendOut(orderOutputDo, req.getTrackId(), userId);
                }
            } else if (orderOutputDo.getStatus().equals(DicBusinessItemConstant.fbaOrderProblemStatus)) {
                this.dealwithOrderSendOut(orderOutputDo, req.getTrackId(), userId);
            }
        } else {
            orderOutputDo.setTrackNumber(req.getTrackNumber());
            updateById(orderOutputDo);
        }
        return null;
    }

    @Override
    public boolean back2Stock(Long id, String fee, String type, Long userId) {

        return false;
    }

    @Override
    public OrderOutputUpdateTrackNumberRes updateTrackNumberInit(Long id, Long userId, Long companyId) {
        FbaOrderOutputDo orderOutputDo = dao.selectById(id);
        if (orderOutputDo == null) {
            throw new BizException(SysConstant.Order_NotExist);
        }
        OrderOutputUpdateTrackNumberRes res = new OrderOutputUpdateTrackNumberRes();
        res.setId(id);
        res.setCurrentTrackId(orderOutputDo.getTrackId());
        res.setTrackNumber(orderOutputDo.getTrackNumber());
        LambdaQueryWrapper<DicBusinessItemDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.fbaOrderOutPutTruck);
        List<DicBusinessItemDo> trackCompanyList = dicBusinessItemDao.selectList(wrapper);
        List<IdAndNameEntity> trackList = new ArrayList<>();
        trackList.add(new IdAndNameEntity(DicBusinessItemConstant.sagawaExpress.intValue(), dicBusinessItemDao.selectById(DicBusinessItemConstant.sagawaExpress).getDicItemValue()));
        trackList.add(new IdAndNameEntity(DicBusinessItemConstant.yamatoExpressNew.intValue(), dicBusinessItemDao.selectById(DicBusinessItemConstant.yamatoExpressNew).getDicItemValue()));
        for (DicBusinessItemDo itemDo : trackCompanyList) {
            trackList.add(new IdAndNameEntity(itemDo.getId().intValue(), itemDo.getDicItemValue()));
        }
        res.setTrackIds(trackList);

        //只有已打单/已约仓/已约车 且未拣货 才展示推荐出库库位
        if (DicBusinessItemConstant.fbaOrderPrintStatus.equals(orderOutputDo.getStatus()) || DicBusinessItemConstant.fbaOrderAppointStorageStatus.equals(orderOutputDo.getStatus()) || DicBusinessItemConstant.fbaOrderAppointCarStatus.equals(orderOutputDo.getStatus())) {
            if (orderOutputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.ToPick.getValue())) {
                //说明未拣货
                BatchPickUpReq pickUpReq = new BatchPickUpReq();
                pickUpReq.setIds(Arrays.asList(id));
                List<BatchPickUpRes> resList = this.batchPickUp(pickUpReq, userId, companyId);
                if (resList.size() == 0) {
                    throw new BizException(SysConstant.Product_Stock_NotEnough);
                }
                res.setShowList(resList.get(0).getShowList());
                res.setPositionAndNumberList(resList.get(0).getPositionAndNumberList());
            } else if (orderOutputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.UnPick.getValue()) || orderOutputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.Picked.getValue())) {
                //已拣货
                StockPickUpDo pickUpDo = stockPickUpDao.selectById(orderOutputDo.getPickUpId());
                if (pickUpDo == null) {
                    throw new BizException(SysConstant.FbaOrder_Pickup_NotMatch);
                }
                StorageDo storageDo = storageDao.selectById(orderOutputDo.getStorageId());
                if (storageDo == null) {
                    throw new BizException(SysConstant.Storage_NotExist);
                }
                //已关联拣货单 锁定了库存，获取锁定库存信息
                List<PositionAndNumberDTO> positionAndNumberList = stockPickUpService.getPostListByOrderId(pickUpDo, id, storageDo.getStorageName());
                res.setPositionAndNumberList(positionAndNumberList);
                res.setShowList(stockPickUpService.getShowList(positionAndNumberList));
            }
//            else if (orderOutputDo.getPickStatus().equals(StaticDict.Pick_Up_Status.UnPick.getValue())) {
//                //待拣货
//                StockPickUpDo pickUpDo = stockPickUpDao.selectById(orderOutputDo.getPickUpId());
//                if (pickUpDo == null) {
//                    throw new BizException(SysConstant.FbaOrder_Pickup_NotMatch);
//                }
//                List<PositionAndNumberDTO> positionAndNumberList = stockPickUpService.getPosList(pickUpDo, new HashSet<>(), orderOutputDo.getId(), true);
//                res.setPositionAndNumberList(positionAndNumberList);
//                res.setShowList(stockPickUpService.getShowList(positionAndNumberList));
//            }
        }
        return res;
    }

    @Override
    public void uploadSignatureFile(FbaOrderOutputUploadFileReq req, Long userId) {
        FbaOrderOutputDo fbaOrderOutputDo = this.baseMapper.selectById(req.getId());
        fileService.deleteFile(fbaOrderOutputDo.getSignatureFileId());
        fbaOrderOutputDo.setSignatureFileId(req.getFileId());
        if (fbaOrderOutputDo.getStatus() < DicBusinessItemConstant.fbaOrderSendOutStatus)
            throw new BizException(GlobalConstants.FBA_NO_OUT);
        updateFbaStatus(fbaOrderOutputDo, DicBusinessItemConstant.fbaOrderSignStatus + "", "签收", userId);
//        this.baseMapper.updateById(fbaOrderOutputDo);
        fileService.uploadFile(req.getFileId());
    }

    @Override
    public void uploadSTrackFile(FbaOrderOutputUploadFileReq req, Long userId) {
        FbaOrderOutputDo fbaOrderOutputDo = this.baseMapper.selectById(req.getId());
        fileService.deleteFile(fbaOrderOutputDo.getTrackFileId());

        fbaOrderOutputDo.setTrackFileId(req.getFileId());
        if (fbaOrderOutputDo.getStatus() < DicBusinessItemConstant.fbaOrderSendOutStatus)
            updateFbaStatus(fbaOrderOutputDo, DicBusinessItemConstant.fbaOrderCheckStatus + "", "审核并上传快递标签", userId);
        this.baseMapper.updateById(fbaOrderOutputDo);
        fileService.uploadFile(req.getFileId());
    }

    @Override
    public void exportSkuTotal(Map<String, String> map, List<Long> ids, HttpServletResponse response) {
        QueryWrapper<FbaOrderOutputDo> wrapper = queryBuild(map);

        if (ids == null) ids = new ArrayList<>();
        final List<Long> orderIdsList = ids;
        if (orderIdsList.size() < 1) {
            List<FbaOrderOutputDo> orderList = dao.selectList(wrapper);
            if (orderList == null) throw new BizException(SysConstant.No_Data);
            orderList.stream().forEach(orderOutputDo -> {
                orderIdsList.add(orderOutputDo.getId());
            });
        }
        List<OrderOutputSkuSumExcelExportVo> skuSumExcelExportVos = new ArrayList<>();
        List<FbaOrderOutputProductDo> productDoList = productDao.selectSkuAndCountListByOrderIds(orderIdsList);
        if (productDoList == null) throw new BizException(SysConstant.No_Data);
        int[] total = new int[1];
        productDoList.stream().sorted().forEach(orderOutputProductDo -> {
            ProductInfoDo productInfoDo = productInfoDao.selectById(orderOutputProductDo.getProductId());
            OrderOutputSkuSumExcelExportVo excelExportVo = new OrderOutputSkuSumExcelExportVo();
            if (productInfoDo != null) {
                excelExportVo.setCommoditySku(productInfoDo.getCommoditySku());
                excelExportVo.setStorageSku(productInfoDo.getStorageSku());
                excelExportVo.setProductName(productInfoDo.getProductName());
                excelExportVo.setTotalCount(orderOutputProductDo.getCount() + "");
                total[0] = total[0] + orderOutputProductDo.getCount();
            }
            skuSumExcelExportVos.add(excelExportVo);
        });
        OrderOutputSkuSumExcelExportVo excelExportVo = new OrderOutputSkuSumExcelExportVo();
        excelExportVo.setProductName("合计");
        excelExportVo.setTotalCount(total[0] + "");
        skuSumExcelExportVos.add(excelExportVo);
        try {
            ExcelUtils.exportExcel(skuSumExcelExportVos, OrderOutputSkuSumExcelExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼SKU小计.xls", new ExportParams(), response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exportPickExcelOne(Long id, HttpServletResponse response) {
        FbaOrderOutputDo orderOutputDo;
        orderOutputDo = this.baseMapper.selectById(id);
        if (orderOutputDo == null) throw new BizException(SysConstant.Order_NotExist);
        StringBuilder stringBuilder = new StringBuilder();
        QueryWrapper wrapper1 = new QueryWrapper();
        FbaOrderOutputSelfStorageExportVo exportVo = new FbaOrderOutputSelfStorageExportVo();
        exportVo.setTips(orderOutputDo.getTips());
        List<FbaOrderOutputSelfStorageExportVo> excelExportVoList = new ArrayList<>();

        StorageDo byId = storageService.getById(orderOutputDo.getStorageId());
        if (byId != null) {
            exportVo.setStorage(byId.getCode());
        }
        if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
            FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
            if (fbaStorageDo != null) {
                exportVo.setFbaStorage(fbaStorageDo.getFbaCode());
                exportVo.setCompanyCode(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
            }
        } else {
            exportVo.setFbaStorage(orderOutputDo.getReceiverName());
            exportVo.setCompanyCode(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
        }
        wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
        List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper1);
        List<FbaOrderOutputCommonPackageExportVo> packageExportVoList = new ArrayList<>();
        int i = 1;
        int packageCount = 0, totalSkuCount = 0;
        for (FbaOrderOutputPackageDo packageDo : packageDoList) {
            StringBuilder commoditySKu = new StringBuilder();
            StringBuilder storageSKu = new StringBuilder();
            int packageSkuCount = 0;
            StringBuilder skuCount = new StringBuilder();
            FbaOrderOutputCommonPackageExportVo packageExportVo = new FbaOrderOutputCommonPackageExportVo();
            BeanUtils.copyProperties(packageDo, packageExportVo);
            packageExportVo.setPackageCount(packageDo.getCount());
            wrapper1 = new QueryWrapper();
            wrapper1.eq("package_id", packageDo.getId());
            List<FbaOrderOutputProductDo> productDoList = productDao.selectList(wrapper1);
            List<FbaOrderOutputCommonProductExportVo> productExcelExportVoList = new ArrayList<>();
            if (productDoList.size() > 0) {
                for (FbaOrderOutputProductDo product : productDoList) {
                    FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
                    ProductInfoDo productInfoDo = productInfoDao.selectById(product.getProductId());
                    productExportVo.setCount(product.getCount());
                    if (productInfoDo != null) {
                        if (commoditySKu.length() > 1) commoditySKu.append(",");
                        commoditySKu.append(productInfoDo.getCommoditySku());
                        if (storageSKu.length() > 1) storageSKu.append(",");
                        storageSKu.append(productInfoDo.getStorageSku());
                        productExportVo.setCommoditySku(productInfoDo.getCommoditySku());
                        productExportVo.setStorageSku(productInfoDo.getStorageSku());
                    }
                    packageSkuCount = packageSkuCount + product.getCount() * packageDo.getCount();
                    if (skuCount.length() > 1) skuCount.append(",");
                    skuCount.append(product.getCount());
                    productExcelExportVoList.add(productExportVo);
                }
            } else {
                FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
                productExcelExportVoList.add(productExportVo);
            }
            if (stringBuilder.length() > 1) stringBuilder.append(",");
            stringBuilder.append(packageDo.getPoNumber());
            packageExportVo.setProductExportVoList(productExcelExportVoList);
            packageExportVo.setCommoditySku(commoditySKu.toString());
            packageExportVo.setStorageSku(storageSKu.toString());
            packageExportVo.setSkuCount(skuCount.toString());
            packageExportVo.setTotalCount(packageSkuCount);
            packageExportVoList.add(packageExportVo);
            packageCount = packageCount + packageDo.getCount();
            totalSkuCount = totalSkuCount + packageSkuCount;
        }
        exportVo.setPackageExportVoList(packageExportVoList);
//                            exportVo.setPoNumber(stringBuilder.toString());
        int count = productDao.selectCountByOrderId(orderOutputDo.getId());
        exportVo.setTotalCount(count);
        excelExportVoList.add(exportVo);
        FbaOrderOutputSelfStorageExportVo exportVoEnd = new FbaOrderOutputSelfStorageExportVo();
        exportVoEnd.setFbaStorage("合計");
        List<FbaOrderOutputCommonPackageExportVo> packageExportVoListEnd = new ArrayList<>();
        FbaOrderOutputCommonPackageExportVo packageExportVoEnd = new FbaOrderOutputCommonPackageExportVo();
        packageExportVoEnd.setPackageCount(packageCount);
        packageExportVoEnd.setTotalCount(totalSkuCount);
        List<FbaOrderOutputCommonProductExportVo> productExportVoList = new ArrayList<>();
        FbaOrderOutputCommonProductExportVo exportVoProduct2 = new FbaOrderOutputCommonProductExportVo();
        productExportVoList.add(exportVoProduct2);
        packageExportVoEnd.setProductExportVoList(productExportVoList);
        packageExportVoListEnd.add(packageExportVoEnd);
        exportVoEnd.setPackageExportVoList(packageExportVoListEnd);
//        excelExportVoList.add(exportVoEnd);
        ExportParams exportParams = new ExportParams();
        StorageDo storageDo = storageService.getById(orderOutputDo);
        if (storageDo == null) storageDo = storageService.getById(orderOutputDo.getStorageId());
        if (storageDo.getId() > 9) {
            FbaOrderOutputSelfStorageExportVo exportVoEnd1 = new FbaOrderOutputSelfStorageExportVo();
            exportVoEnd1.setCompanyCode("拣货人:");
            exportVoEnd1.setStorage("复核人:");
            List<FbaOrderOutputCommonPackageExportVo> packageExportVoListEnd1 = new ArrayList<>();
            FbaOrderOutputCommonPackageExportVo packageExportVoEnd1 = new FbaOrderOutputCommonPackageExportVo();
            exportVoEnd1.setFbaStorage("箱标文件");
            packageExportVoEnd1.setUpcNumber(orderOutputDo.getFileId() + "");
            packageExportVoEnd1.setPoNumber("产品标文件");
            packageExportVoEnd1.setPackageCount(packageCount);
            packageExportVoEnd1.setTotalCount(totalSkuCount);
            packageExportVoListEnd1.add(packageExportVoEnd1);
            List<FbaOrderOutputCommonProductExportVo> productExportVoListEnd1 = new ArrayList<>();
            FbaOrderOutputCommonProductExportVo productExportVoEnd1 = new FbaOrderOutputCommonProductExportVo();
            productExportVoEnd1.setCommoditySku(orderOutputDo.getProductFileId() + "");
            productExportVoEnd1.setStorageSku(orderOutputDo.getProductFileId() + "");
            productExportVoEnd1.setStorageSku("对照文件");
            if (orderOutputDo.getOtherFileId() != null)
                productExportVoEnd1.setCount(orderOutputDo.getOtherFileId().intValue());
            productExportVoListEnd1.add(productExportVoEnd1);
            packageExportVoEnd1.setProductExportVoList(productExportVoListEnd1);
            exportVoEnd1.setPackageExportVoList(packageExportVoListEnd1);
            excelExportVoList.add(exportVoEnd1);
        }
        exportParams.setStyle(ExcelExportStylerBorderImpl.class);
        exportParams.setTitle(storageDo.getCode() + " " + TimeUtils.getCurrentDateFormat() + "  " + getFbaTrackCode(orderOutputDo.getTrackId()) + "  FBA拣货订单" + (orderOutputDo.getIsTrucks() == 1 ? "(已拼车)" : "(未拼车)"));
        try {
            if (storageDo.getId() > 9) {
                ExcelUtils.exportExcel(excelExportVoList, FbaOrderOutputSelfStorageExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
            } else {
                ExcelUtils.exportExcel(excelExportVoList, FbaOrderOutputCommonExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String getFbaTrackCode(Long trackId) {
        DicBusinessItemDo itemDo = dicBusinessItemDao.selectById(trackId);
        if (trackId == 8) {
            return "SAGAWA";
        } else if (trackId == 65) {
            return "GreenBox";
        } else if (trackId == 66) {
            return "SEINO";
        } else if (itemDo != null) {
            return itemDo.getDicItemValue();
        }
        return null;
    }

    @Override
    public void exportPickExcel(Map<String, String> map, List<Long> ids, HttpServletResponse response) {
        QueryWrapper<FbaOrderOutputDo> wrapper = queryBuild(map);
        List<FbaOrderOutputDo> orderOutputDoList;
        if (ids != null && ids.size() > 0) {
            orderOutputDoList = this.baseMapper.selectBatchIds(ids);
        } else {
            orderOutputDoList = this.baseMapper.selectList(wrapper);
        }
        List<FbaOrderOutputSelfStorageExportVo> excelExportVoList = new ArrayList<>();
        switch (map.get("trackId")) {
            default:
                final int[] packageCount = {0};
                final int[] totalSkuCount = {0};
                orderOutputDoList.stream().forEach(orderOutputDo -> {
                    StringBuilder stringBuilder = new StringBuilder();
                    QueryWrapper wrapper1 = new QueryWrapper();
                    FbaOrderOutputSelfStorageExportVo exportVo = new FbaOrderOutputSelfStorageExportVo();
                    exportVo.setTips(orderOutputDo.getTips());

                    StorageDo byId = storageService.getById(orderOutputDo.getStorageId());
                    if (byId != null) {
                        exportVo.setStorage(byId.getCode());
                    }
                    if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
                        FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
                        if (fbaStorageDo != null) {
                            exportVo.setFbaStorage(fbaStorageDo.getFbaCode());
                            exportVo.setCompanyCode(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
                        }
                    } else {
                        exportVo.setFbaStorage(orderOutputDo.getReceiverName());
                        exportVo.setCompanyCode(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
                    }
                    wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
                    List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper1);
                    List<FbaOrderOutputCommonPackageExportVo> packageExportVoList = new ArrayList<>();
                    int i = 1;
                    for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                        StringBuilder commoditySKu = new StringBuilder();
                        StringBuilder storageSKu = new StringBuilder();
                        int packageSkuCount = 0;
                        StringBuilder skuCount = new StringBuilder();
                        FbaOrderOutputCommonPackageExportVo packageExportVo = new FbaOrderOutputCommonPackageExportVo();
                        BeanUtils.copyProperties(packageDo, packageExportVo);
                        packageExportVo.setPackageCount(packageDo.getCount());
                        wrapper1 = new QueryWrapper();
                        wrapper1.eq("package_id", packageDo.getId());
                        List<FbaOrderOutputProductDo> productDoList = productDao.selectList(wrapper1);
                        List<FbaOrderOutputCommonProductExportVo> productExcelExportVoList = new ArrayList<>();
                        if (productDoList.size() > 0) {
                            for (FbaOrderOutputProductDo product : productDoList) {
                                FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
                                ProductInfoDo productInfoDo = productInfoDao.selectById(product.getProductId());
                                productExportVo.setCount(product.getCount());
                                if (productInfoDo != null) {
                                    if (commoditySKu.length() > 1) commoditySKu.append(",");
                                    commoditySKu.append(productInfoDo.getCommoditySku());
                                    if (storageSKu.length() > 1) storageSKu.append(",");
                                    storageSKu.append(productInfoDo.getStorageSku());
                                    productExportVo.setCommoditySku(productInfoDo.getCommoditySku());
                                    productExportVo.setStorageSku(productInfoDo.getStorageSku());
                                }
                                packageSkuCount = packageSkuCount + product.getCount() * packageDo.getCount();
                                if (skuCount.length() > 1) skuCount.append(",");
                                skuCount.append(product.getCount());
                                productExcelExportVoList.add(productExportVo);
                            }
                        } else {
                            FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
                            productExcelExportVoList.add(productExportVo);
                        }
                        if (stringBuilder.length() > 1) stringBuilder.append(",");
                        stringBuilder.append(packageDo.getPoNumber());
                        packageExportVo.setProductExportVoList(productExcelExportVoList);
                        packageExportVo.setCommoditySku(commoditySKu.toString());
                        packageExportVo.setStorageSku(storageSKu.toString());
                        packageExportVo.setSkuCount(skuCount.toString());
                        packageExportVo.setTotalCount(packageSkuCount);
                        packageExportVoList.add(packageExportVo);
                        packageCount[0] = packageCount[0] + packageDo.getCount();
                        totalSkuCount[0] = totalSkuCount[0] + packageSkuCount;
                    }
                    exportVo.setPackageExportVoList(packageExportVoList);
//                            exportVo.setPoNumber(stringBuilder.toString());
                    int count = productDao.selectCountByOrderId(orderOutputDo.getId());
                    exportVo.setTotalCount(count);
                    excelExportVoList.add(exportVo);
                });
                FbaOrderOutputSelfStorageExportVo exportVoEnd = new FbaOrderOutputSelfStorageExportVo();
                exportVoEnd.setFbaStorage("合計");
                List<FbaOrderOutputCommonPackageExportVo> packageExportVoListEnd = new ArrayList<>();
                FbaOrderOutputCommonPackageExportVo packageExportVoEnd = new FbaOrderOutputCommonPackageExportVo();
                packageExportVoEnd.setPackageCount(packageCount[0]);
                packageExportVoEnd.setTotalCount(totalSkuCount[0]);
                List<FbaOrderOutputCommonProductExportVo> productExportVoList = new ArrayList<>();
                FbaOrderOutputCommonProductExportVo exportVo = new FbaOrderOutputCommonProductExportVo();
                productExportVoList.add(exportVo);
                packageExportVoEnd.setProductExportVoList(productExportVoList);
                packageExportVoListEnd.add(packageExportVoEnd);
                exportVoEnd.setPackageExportVoList(packageExportVoListEnd);
                excelExportVoList.add(exportVoEnd);
                ExportParams exportParams = new ExportParams();
                String storageId = map.get("storageId");
                StorageDo storageDo = storageService.getById(storageId);
                if (storageDo == null) storageDo = storageService.getById(orderOutputDoList.get(0).getStorageId());
                if (storageDo.getId() > 9) {
                    FbaOrderOutputSelfStorageExportVo exportVoEnd1 = new FbaOrderOutputSelfStorageExportVo();
                    exportVoEnd1.setCompanyCode("拣货人:");
                    exportVoEnd1.setFbaStorage("复核人:");
                    excelExportVoList.add(exportVoEnd1);
                }
                exportParams.setStyle(ExcelExportStylerBorderImpl.class);
                exportParams.setTitle(storageDo.getCode() + " " + TimeUtils.getCurrentDateFormat() + "  FBA拣货订单");
                try {
                    if (storageDo.getId() > 9) {
                        ExcelUtils.exportExcel(excelExportVoList, FbaOrderOutputSelfStorageExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
                    } else {
                        ExcelUtils.exportExcel(excelExportVoList, FbaOrderOutputCommonExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response)
                break;
        }
    }

    /**
     * 批量拣货 导出
     *
     * @param pickUpdIds
     * @param response
     */
    @Override
    public void exportPickUp(List<Long> pickUpdIds, HttpServletResponse response) {
        List<FbaOrderOutputDo> orderList = dao.selectList(new LambdaQueryWrapper<FbaOrderOutputDo>().in(FbaOrderOutputDo::getPickUpId, pickUpdIds));
        if (orderList.size() != pickUpdIds.size()) {
            throw new BizException(SysConstant.Order_NotMatch_Pickup);
        }
//        List<FbaOrderExportVo> exportVoList = new ArrayList<>();
//        for (FbaOrderOutputDo et : orderList) {
//            FbaOrderExportVo exportVo = new FbaOrderExportVo();
//
//            CompanyDo companyDo = companyDao.selectById(et.getCompanyId());
//            if (companyDo == null) {
//                throw new BizException(SysConstant.Error_Company_NotMatch);
//            }
//            exportVo.setCompanyCode(companyDo.getCompanyCode());
//            StorageDo byId = storageService.getById(et.getStorageId());
//            if (byId != null) {
//                exportVo.setStorage(byId.getCode());
//            }
//            if (et.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
//                FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(et.getFbaStorageId());
//                if (fbaStorageDo != null) {
//                    exportVo.setFbaStorage(fbaStorageDo.getFbaCode());
//                }
//            } else {
//                exportVo.setFbaStorage(et.getReceiverName());
//            }
//            exportVo.setTips(et.getTips());
//
//            //包裹商品信息
//            List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(new LambdaQueryWrapper<FbaOrderOutputPackageDo>().eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, et.getId()));
//            List<FbaOrderPackageExportVo> packageExportVoList = new ArrayList<>();
//            for (FbaOrderOutputPackageDo packageDo : packageDoList) {
//                FbaOrderPackageExportVo packageExportVo = new FbaOrderPackageExportVo();
//                packageExportVo.setPoNumber(packageDo.getPoNumber());
//                packageExportVo.setUpcNumber(packageDo.getUpcNumber());
//                packageExportVo.setPackageCount(packageDo.getCount());
//                packageExportVo.setTips(packageDo.getTips());
//
//                int total = 0;
//                List<FbaOrderOutputProductDo> productDoList = productDao.selectList(new LambdaQueryWrapper<FbaOrderOutputProductDo>().eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId()));
//                //计算一个包裹 的 总件数
//                List<FbaOrderProductExportVo> productExportVoList = new ArrayList<>();
//                for (FbaOrderOutputProductDo productDo : productDoList) {
//                    //商品导出信息
//                    FbaOrderProductExportVo productExportVo = new FbaOrderProductExportVo();
//
//                    ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
//                    if (productInfoDo == null) {
//                        throw new BizException(SysConstant.Product_NotExist);
//                    }
//                    productExportVo.setCommoditySku(productInfoDo.getCommoditySku());
//                    productExportVo.setStorageSku(productInfoDo.getStorageSku());
//                    productExportVo.setCount(productDo.getCount());
//
//                    //库位信息
//                    List<FbaOrderRackExportVo> rackExportVoList = new ArrayList<>();
//                    //这个包裹的商品下面按照 库位合并
//                    List<StockPickUpRackDto> pickUpDetailDoList = stockPickUpDetailDao.getPickUpRackList(et.getPickUpId(), et.getId(), productDo.getProductId());
//                    total += packageDo.getCount() * productDo.getCount();
//                    int count = packageDo.getCount() * productDo.getCount();//这个商品在这个包裹的总件数
//                    for (StockPickUpRackDto pickUpDetailDo : pickUpDetailDoList) {
//                        FbaOrderRackExportVo rackExportVo = new FbaOrderRackExportVo();
//                        if (pickUpDetailDo.getNumber() >= count) {
//                            rackExportVo.setCount(count);
//                            count = 0;
//                        } else {
//                            rackExportVo.setCount(pickUpDetailDo.getNumber());
//                            count -= pickUpDetailDo.getNumber();
//                        }
//                        //库位名称
//
//                        rackExportVo.setRackName(pickUpDetailDo.getRackName());
//                        rackExportVoList.add(rackExportVo);
//                        if (count <= 0) {
//                            break;
//                        }
//                    }
//                    if (count > 0) {
//                        throw new BizException(SysConstant.Order_PickupCount_Error);
//                    }
//                    productExportVo.setList(rackExportVoList);
//                    productExportVoList.add(productExportVo);
//                }
//                packageExportVo.setTotalCount(total);
//                packageExportVo.setList(productExportVoList);
//                packageExportVoList.add(packageExportVo);
//            }
//            exportVo.setList(packageExportVoList);
//            exportVoList.add(exportVo);
//        }
//        ExportParams exportParams = new ExportParams();
//        exportParams.setCreateHeadRows(true);
//        exportParams.setHeaderColor(IndexedColors.YELLOW.getIndex());
//        exportParams.setTitle(TimeUtils.getCurrentDateFormat() + "  FBA拣货订单");
//        try {
////            ExcelUtils.exportExcelToSave(exportVoList, FbaOrderExportVo.class, "拣货单" + DateUtils.dateFormatToString(new Date(), "yyyyMMddHHmmss") + ".xlsx", exportParams, filePathTemp);
//            ExcelUtils.exportOutPut(exportVoList, FbaOrderExportVo.class, "拣货单" + DateUtils.dateFormatToString(new Date(), "yyyyMMddHHmmss"), exportParams, response);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }


        //新版自定义导出 @Excel导出面对多层 合并有问题
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
        XSSFSheet sheet = xssfWorkbook.createSheet("拣货明细");
        String[] headers = new String[]{"公司", "備考1", "出荷先", "AmazonFC", "FNSKU/UPC", "PO", "製品SKU", "在庫確認SKU", "库位名称", "拣货数量", "内装数", "箱数", "总件数", "備考2"};


        CellStyle midStyle = xssfWorkbook.createCellStyle();
        midStyle.setAlignment(HorizontalAlignment.CENTER); //水平居中
        midStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        XSSFRow titleRow = sheet.createRow(0);//第一行
        titleRow.setHeight((short) 500);
        XSSFCell titleRowCell = titleRow.createCell(0);
        titleRowCell.setCellStyle(midStyle);
        titleRowCell.setCellValue(TimeUtils.getCurrentDateFormat() + "  FBA拣货订单");
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.length - 1));

        XSSFRow firstRow = sheet.createRow(1);//第一行
        firstRow.setHeight((short) 500);
        for (int i = 0; i < headers.length; i++) {
            XSSFCell firstRowCell = firstRow.createCell(i);
            firstRowCell.setCellValue(headers[i]);
            firstRowCell.setCellStyle(midStyle);
        }
        sheet.setColumnWidth(3, 256 * 15);
        sheet.setColumnWidth(4, 256 * 15);
        sheet.setColumnWidth(6, 256 * 15);
        sheet.setColumnWidth(7, 256 * 15);
        sheet.setColumnWidth(8, 256 * 15);
        sheet.setColumnWidth(13, 256 * 17);

        int totalCase = 0; //总箱数
        int rowIndex = 2;//创建第几行
        for (int i = 0; i < orderList.size(); i++) {//主订单信息
            FbaOrderOutputDo et = orderList.get(i);
            CompanyDo companyDo = companyDao.selectById(et.getCompanyId());
            if (companyDo == null) {
                throw new BizException(SysConstant.Error_Company_NotMatch);
            }
            StorageDo byId = storageService.getById(et.getStorageId());
            FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(et.getFbaStorageId());

            int orderMergeIndex = rowIndex;//主订单合并开始行

            //包裹商品信息
            List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(new LambdaQueryWrapper<FbaOrderOutputPackageDo>().eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, et.getId()));
            for (int j = 0; j < packageDoList.size(); j++) {
                FbaOrderOutputPackageDo packageDo = packageDoList.get(j);
                totalCase += packageDo.getCount();
                int total = 0;
                //产品信息
                List<FbaOrderOutputProductDo> productDoList = productDao.selectList(new LambdaQueryWrapper<FbaOrderOutputProductDo>().eq(FbaOrderOutputProductDo::getPackageId, packageDo.getId()));

                //计算总件数
                for (FbaOrderOutputProductDo productDo : productDoList) {
                    total += packageDo.getCount() * productDo.getCount();
                }
                int packageCountMergeIndex = rowIndex;//箱数合并开始

                for (int p = 0; p < productDoList.size(); p++) {
                    FbaOrderOutputProductDo productDo = productDoList.get(p);

                    ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                    if (productInfoDo == null) {
                        throw new BizException(SysConstant.Product_NotExist);
                    }
                    //库位信息 这个包裹的商品下面按照 库位合并
                    List<StockPickUpRackDto> pickUpDetailDoList = stockPickUpDetailDao.getPickUpRackList(et.getPickUpId(), et.getId(), productDo.getProductId());
                    int count = packageDo.getCount() * productDo.getCount();//这个商品在这个包裹的总件数
                    int productCountMergeIndex = rowIndex;//内装数合并开始
                    for (StockPickUpRackDto pickUpDetailDo : pickUpDetailDoList) {
                        XSSFRow row = sheet.createRow(rowIndex);
                        row.setHeight((short) 500);
                        //主订单信息填充
                        XSSFCell companyCodeCell = row.createCell(0);//公司
                        companyCodeCell.setCellValue(companyDo.getCompanyCode());
                        companyCodeCell.setCellStyle(midStyle);

                        XSSFCell tips1Cell = row.createCell(1);//備考1
                        tips1Cell.setCellValue(et.getTips());
                        tips1Cell.setCellStyle(midStyle);

                        XSSFCell storageCell = row.createCell(2);//出荷先
                        if (byId != null) {
                            storageCell.setCellValue(byId.getCode());
                        }
                        storageCell.setCellStyle(midStyle);

                        XSSFCell fbaStorageCell = row.createCell(3);//AmazonFC
                        if (et.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
                            if (fbaStorageDo != null) {
                                fbaStorageCell.setCellValue(fbaStorageDo.getFbaCode());
                            }
                        } else {
                            fbaStorageCell.setCellValue(et.getReceiverName());
                        }
                        fbaStorageCell.setCellStyle(midStyle);

                        //包裹信息填充
                        XSSFCell upcNumberCell = row.createCell(4);//PO
                        upcNumberCell.setCellValue(packageDo.getUpcNumber());
                        upcNumberCell.setCellStyle(midStyle);

                        XSSFCell poNumberCell = row.createCell(5);//PO
                        poNumberCell.setCellValue(packageDo.getPoNumber());
                        poNumberCell.setCellStyle(midStyle);

                        XSSFCell packageCountCell = row.createCell(11);//箱数
                        packageCountCell.setCellValue(packageDo.getCount());
                        packageCountCell.setCellStyle(midStyle);

                        XSSFCell packageTotalCountCell = row.createCell(12);//总件数
                        packageTotalCountCell.setCellValue(total);
                        packageTotalCountCell.setCellStyle(midStyle);

                        XSSFCell tips2Cell = row.createCell(13);//備考2
                        tips2Cell.setCellValue(packageDo.getTips());
                        tips2Cell.setCellStyle(midStyle);

                        //产品信息填充
                        XSSFCell commoditySkuCell = row.createCell(6);//製品SKU
                        commoditySkuCell.setCellValue(productInfoDo.getCommoditySku());
                        commoditySkuCell.setCellStyle(midStyle);

                        XSSFCell storageSkuCell = row.createCell(7);//在庫確認SKU
                        storageSkuCell.setCellValue(productInfoDo.getStorageSku());
                        storageSkuCell.setCellStyle(midStyle);

                        XSSFCell productCountCell = row.createCell(10);//内装数
                        productCountCell.setCellValue(productDo.getCount());
                        productCountCell.setCellStyle(midStyle);

                        //库位信息填充
                        XSSFCell rackNameCell = row.createCell(8);//库位名称
                        rackNameCell.setCellValue(pickUpDetailDo.getRackName());
                        rackNameCell.setCellStyle(midStyle);

                        XSSFCell rackCountCell = row.createCell(9, CellType.NUMERIC);//库位拣货数量
                        if (pickUpDetailDo.getNumber() >= count) {
                            rackCountCell.setCellValue(count);
                            count = 0;
                        } else {
                            rackCountCell.setCellValue(pickUpDetailDo.getNumber());
                            count -= pickUpDetailDo.getNumber();
                        }
                        rackCountCell.setCellStyle(midStyle);
                        rowIndex++;
                        //库位名称
                        if (count <= 0) {
                            break;
                        }
                    }
                    if (productCountMergeIndex < rowIndex - 1) {
                        sheet.addMergedRegion(new CellRangeAddress(productCountMergeIndex, rowIndex - 1, 10, 10));
                    }
                    if (count > 0) {
                        throw new BizException(SysConstant.Order_PickupCount_Error);
                    }
                }
                if (packageCountMergeIndex != rowIndex - 1 && productDoList.size() != 0) {
                    sheet.addMergedRegion(new CellRangeAddress(packageCountMergeIndex, rowIndex - 1, 11, 11));
                    sheet.addMergedRegion(new CellRangeAddress(packageCountMergeIndex, rowIndex - 1, 12, 12));
                    sheet.addMergedRegion(new CellRangeAddress(packageCountMergeIndex, rowIndex - 1, 13, 13));

                    sheet.addMergedRegion(new CellRangeAddress(packageCountMergeIndex, rowIndex - 1, 4, 4));
                    sheet.addMergedRegion(new CellRangeAddress(packageCountMergeIndex, rowIndex - 1, 5, 5));
                }
            }
            if (orderMergeIndex != rowIndex - 1 && packageDoList.size() != 0) {
                sheet.addMergedRegion(new CellRangeAddress(orderMergeIndex, rowIndex - 1, 0, 0));
                sheet.addMergedRegion(new CellRangeAddress(orderMergeIndex, rowIndex - 1, 1, 1));
                sheet.addMergedRegion(new CellRangeAddress(orderMergeIndex, rowIndex - 1, 2, 2));
                sheet.addMergedRegion(new CellRangeAddress(orderMergeIndex, rowIndex - 1, 3, 3));
            }
            XSSFRow row = sheet.createRow(rowIndex);
            row.setHeight((short) 500);
            XSSFCell companyCodeCell = row.createCell(0);//公司
            companyCodeCell.setCellValue("合计");
            companyCodeCell.setCellStyle(midStyle);

            XSSFCell packageCountCell = row.createCell(11);//箱数
            packageCountCell.setCellValue(totalCase);
            packageCountCell.setCellStyle(midStyle);
        }

        ExcelUtils.exportUtils(xssfWorkbook, "拣货单" + DateUtils.dateFormatToString(new Date(), "yyyyMMddHHmmss"), filePathTemp, response);

    }

//
//    @Override
//    public void exportPickExcel(Map<String, String> map, List<Long> ids, HttpServletResponse response) {
//        QueryWrapper<FbaOrderOutputDo> wrapper = queryBuild(map);
//        List<FbaOrderOutputDo> orderOutputDoList;
//        if (ids != null && ids.size() > 0) {
//            orderOutputDoList = this.baseMapper.selectBatchIds(ids);
//        } else {
//            orderOutputDoList = this.baseMapper.selectList(wrapper);
//        }
//        List<FbaOrderOutputSelfStorageExportVo> excelExportVoList = new ArrayList<>();
//        List<FbaOrderOutputCommonPackageExportVo> packageExportVoList = new ArrayList<>();
//        switch (map.get("trackId")) {
//            default:
//                final int[] packageCount = {0};
//                orderOutputDoList.stream()
//                        .forEach(orderOutputDo -> {
//                            StringBuilder stringBuilder = new StringBuilder();
//                            QueryWrapper wrapper1 = new QueryWrapper();
//                            FbaOrderOutputSelfStorageExportVo exportVo = new FbaOrderOutputSelfStorageExportVo();
//                            exportVo.setTips(orderOutputDo.getTips());
//                            exportVo.setStorage(storageDao.selectById(orderOutputDo.getStorageId()).getCode());
//                            if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
//                                FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
//                                if (fbaStorageDo != null) {
//                                    exportVo.setFbaStorage(fbaStorageDo.getFbaCode());
//                                    exportVo.setCompanyCode(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
//                                }
//                            } else {
//                                exportVo.setFbaStorage(orderOutputDo.getReceiverName());
//                                exportVo.setCompanyCode(companyDao.selectById(orderOutputDo.getCompanyId()).getCompanyCode());
//                            }
//                            excelExportVoList.add(exportVo);
//                            wrapper1.eq("fba_order_output_id", orderOutputDo.getId());
//                            List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper1);
//
//                            int i = 1;
//                            for (FbaOrderOutputPackageDo packageDo : packageDoList) {
//                                StringBuilder commoditySKu = new StringBuilder();
//                                StringBuilder storageSKu = new StringBuilder();
//                                int packageSkuCount = 0;
//                                StringBuilder skuCount = new StringBuilder();
//                                FbaOrderOutputCommonPackageExportVo packageExportVo = new FbaOrderOutputCommonPackageExportVo();
//                                BeanUtils.copyProperties(packageDo, packageExportVo);
//                                packageExportVo.setPackageCount(packageDo.getCount());
//                                wrapper1 = new QueryWrapper();
//                                wrapper1.eq("package_id", packageDo.getId());
//                                List<FbaOrderOutputProductDo> productDoList = productDao.selectList(wrapper1);
//                                List<FbaOrderOutputCommonProductExportVo> productExcelExportVoList = new ArrayList<>();
//                                if (productDoList.size() > 0) {
//                                    for (FbaOrderOutputProductDo product : productDoList) {
//                                        FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
//                                        ProductInfoDo productInfoDo = productInfoDao.selectById(product.getProductId());
//                                        productExportVo.setCount(product.getCount());
//                                        if (productInfoDo != null) {
//                                            if (commoditySKu.length() > 1)
//                                                commoditySKu.append(",");
//                                            commoditySKu.append(productInfoDo.getCommoditySku());
//                                            if (storageSKu.length() > 1)
//                                                storageSKu.append(",");
//                                            storageSKu.append(productInfoDo.getStorageSku());
//                                            productExportVo.setCommoditySku(productInfoDo.getCommoditySku());
//                                            productExportVo.setStorageSku(productInfoDo.getStorageSku());
//
//                                        }
//                                        packageSkuCount = packageSkuCount + product.getCount() * packageDo.getCount();
//                                        if (skuCount.length() > 1)
//                                            skuCount.append(",");
//                                        skuCount.append(product.getCount());
//                                        productExcelExportVoList.add(productExportVo);
//                                    }
//                                } else {
//                                    FbaOrderOutputCommonProductExportVo productExportVo = new FbaOrderOutputCommonProductExportVo();
//                                    productExcelExportVoList.add(productExportVo);
//                                }
//                                exportVo.setProductExportVoList(productExcelExportVoList);
//
//                                if (stringBuilder.length() > 1)
//                                    stringBuilder.append(",");
//                                stringBuilder.append(packageDo.getPoNumber());
//                                packageExportVo.setProductExportVoList(productExcelExportVoList);
//                                packageExportVo.setCommoditySku(commoditySKu.toString());
//                                packageExportVo.setStorageSku(storageSKu.toString());
//                                packageExportVo.setSkuCount(skuCount.toString());
//
//                                if (orderOutputDo.getStorageType().equals(SysConstant.FBA_ADDRESS)) {
//                                    FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
//                                    if (fbaStorageDo != null) {
//                                        packageExportVo.setFbaStorage(fbaStorageDo.getFbaCode());
//                                    }
//                                } else {
//                                    packageExportVo.setFbaStorage(orderOutputDo.getReceiverName());
//                                }
//                                packageExportVoList.add(packageExportVo);
//                                exportVo.setPoNumber(stringBuilder.toString());
//                                exportVo.setUpcNumber(packageExportVo.getUpcNumber());
//                                exportVo.setPackageCount(packageDo.getCount());
//                                excelExportVoList.add(exportVo);
//
//                                packageCount[0] = packageCount[0] + packageDo.getCount();
//                            }
//                        });
//
//                List<FbaOrderOutputCommonPackageExportVo> packageExportVoListEnd = new ArrayList<>();
//                FbaOrderOutputCommonPackageExportVo packageExportVoEnd = new FbaOrderOutputCommonPackageExportVo();
//                packageExportVoEnd.setFbaStorage("合計");
//                packageExportVoEnd.setPackageCount(packageCount[0]);
//                List<FbaOrderOutputCommonProductExportVo> productExportVoList = new ArrayList<>();
//                productExportVoList.add(new FbaOrderOutputCommonProductExportVo());
//                packageExportVoEnd.setProductExportVoList(productExportVoList);
//                packageExportVoListEnd.add(packageExportVoEnd);
//                packageExportVoList.add(packageExportVoEnd);
//
//                List<FbaOrderOutputSelfStorageExportVo> StorageExportEnd = new ArrayList<>();
//                FbaOrderOutputSelfStorageExportVo exportVoEnd = new FbaOrderOutputSelfStorageExportVo();
//                exportVoEnd.setStorage("合計");
//                exportVoEnd.setPackageCount(packageCount[0]);
//                exportVoEnd.setProductExportVoList(productExportVoList);
//                List<FbaOrderOutputCommonProductExportVo> exportVoList = new ArrayList<>();
//                FbaOrderOutputCommonProductExportVo exportVo = new FbaOrderOutputCommonProductExportVo();
//                exportVoList.add(exportVo);
//                exportVoEnd.setProductExportVoList(exportVoList);
//                excelExportVoList.add(exportVoEnd);
//
//                ExportParams exportParams = new ExportParams("PACKAGE INFO", "PACKAGE INFO");
//                if (StringUtils.isBlank(map.get("storageId"))||Integer.valueOf(map.get("storageId")) >= 9) {
//                    FbaOrderOutputSelfStorageExportVo exportVoEnd1 = new FbaOrderOutputSelfStorageExportVo();
//                    exportVoEnd1.setCompanyCode("拣货人:");
//                    exportVoEnd1.setStorage("复核人:");
//                    List<FbaOrderOutputCommonProductExportVo> productExportVoList1 = new ArrayList<>();
//                    exportVoEnd1.setProductExportVoList(productExportVoList1);
//                    List<FbaOrderOutputCommonProductExportVo> exportVoList1 = new ArrayList<>();
//                    FbaOrderOutputCommonProductExportVo exportVo1 = new FbaOrderOutputCommonProductExportVo();
//                    exportVoList1.add(exportVo1);
//                    exportVoEnd1.setProductExportVoList(exportVoList1);
//                    excelExportVoList.add(exportVoEnd1);
//                }
//                exportParams.setStyle(ExcelExportStylerBorderImpl.class);
//                try {
//                    if (StringUtils.isBlank(map.get("storageId"))||Integer.valueOf(map.get("storageId")) >= 9) {
//                        ExcelUtils.exportExcel(excelExportVoList, FbaOrderOutputSelfStorageExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
//                    } else {
//                        ExcelUtils.exportExcel(packageExportVoList, FbaOrderOutputCommonPackageExportVo.class, TimeUtils.getCurrentDateFormat() + "出荷依頼.xls", exportParams, response);
//                    }
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//                //exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response)
//                break;
//        }
//    }

    private Long getProductId(String sellerSku, Long companyId) {
        sellerSku.trim().replaceAll("\\n", "").replaceAll("　", "");
        LambdaQueryWrapper<ProductInfoDo> productWrapper = new LambdaQueryWrapper();
        productWrapper.eq(ProductInfoDo::getCompanyId, companyId);
        productWrapper.and(product -> {
            product.eq(ProductInfoDo::getCommoditySku, sellerSku).or().eq(ProductInfoDo::getStorageSku, sellerSku);
        });
        ProductInfoDo productInfoDo = productInfoDao.selectOne(productWrapper);
        if (productInfoDo == null) {
            QueryWrapper skuWrapper = new QueryWrapper();
            skuWrapper.eq("sub_sku", sellerSku);
            skuWrapper.eq("company_id", companyId);
            ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
            if (productSkuMapDo == null) {
                throw new BizException(SysConstant.Product_NotExist_Sku, sellerSku);
            }
            return productSkuMapDo.getProductInfoId();
        } else {
            return productInfoDo.getId();
        }
    }

    private ProductInfoDo getProductInfo(String sellerSku, Long companyId) {
        QueryWrapper productWrapper = new QueryWrapper();
        productWrapper.eq("commodity_sku", sellerSku);
        productWrapper.eq("company_id", companyId);
        ProductInfoDo productInfoDo = productInfoDao.selectOne(productWrapper);
        if (productInfoDo == null) {
            QueryWrapper skuWrapper = new QueryWrapper();
            skuWrapper.eq("sub_sku", sellerSku);
            skuWrapper.eq("company_id", companyId);
            ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
            if (productSkuMapDo == null) {
                throw new BizException(SysConstant.Product_NotExist_Sku, sellerSku);
            }
            return productInfoDao.selectById(productSkuMapDo.getProductInfoId());
        } else {
            return productInfoDo;
        }
    }

    private Long getFbaStorageId(Long fbaOrigionId, Long storageId, String postCode) {
        Long fbaStorageId = 0L;
        if (fbaOrigionId == null || fbaOrigionId == 86L) {
            LambdaQueryWrapper<FbaStorageDo> fbaStorageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            JpRegionDo regionDo = regionService.getRegionDoByPostCode(postCode);
            Long regionId = 9L;
            if (regionDo == null) {
                if (storageId == 1 || storageId == 10 || storageId == 11) {
                    regionId = 9L;
                } else {
                    regionId = 22L;
                }
            } else {
                regionId = regionDo.getId();
            }
            fbaStorageDoLambdaQueryWrapper.eq(FbaStorageDo::getReginJpId, regionId).le(FbaStorageDo::getId, 26).orderByDesc(FbaStorageDo::getId).last("limit 1");
            FbaStorageDo storageDo = fbaStorageDao.selectOne(fbaStorageDoLambdaQueryWrapper);
            if (storageDo == null) {
                if (storageId == 1 || storageId == 10 || storageId == 11) {
                    fbaStorageId = 9L;
                } else {
                    fbaStorageId = 22L;
                }
            } else {
                fbaStorageId = storageDo.getId();
            }
        } else if (fbaOrigionId > 26) {
            LambdaQueryWrapper<FbaStorageDo> fbaStorageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            FbaStorageDo storageDo1 = fbaStorageDao.selectById(fbaOrigionId);
            if (storageDo1 == null) {
                throw new BizException(SysConstant.Error_No_FbaStorage);
            }
            fbaStorageDoLambdaQueryWrapper.eq(FbaStorageDo::getReginJpId, storageDo1.getReginJpId()).le(FbaStorageDo::getId, 26).orderByDesc(FbaStorageDo::getId).last("limit 1");
            FbaStorageDo storageDo = fbaStorageDao.selectOne(fbaStorageDoLambdaQueryWrapper);
            fbaStorageId = storageDo.getId();
        } else {
            fbaStorageId = fbaOrigionId;
        }
        return fbaStorageId;
    }

    private FbaShipPriceRes getShipPriceWithReason(double size, double weight, int sizeType, Long storageId, Long
            trackId, Long fbaStorageId, int shipPriceVersion) {
        FbaShipPriceRes res = new FbaShipPriceRes();
        //先判断 size type 原因
        FbaDimensDo et = fbaDimensDao.selectOne(new LambdaQueryWrapper<FbaDimensDo>().eq(FbaDimensDo::getType, sizeType).eq(FbaDimensDo::getStorageId, storageId).eq(FbaDimensDo::getTrackId, trackId).orderByDesc(FbaDimensDo::getSize).last(" limit 1"));
        //如果查不到 说明sizeType 值不对 1或 2 类型  1 按三边计算 2按体积计算
        if (et == null) {
            res.setType("sizeTypeReason");
            return res;
        }

        LambdaQueryWrapper<FbaDimensDo> fbaDimensDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        fbaDimensDoLambdaQueryWrapper.ge(FbaDimensDo::getSize, size).ge(FbaDimensDo::getWeight, weight).eq(FbaDimensDo::getType, sizeType).eq(FbaDimensDo::getStorageId, storageId).eq(FbaDimensDo::getTrackId, trackId).orderByAsc(FbaDimensDo::getSize).last("limit 1");

        FbaDimensDo fbaDimensDo = fbaDimensDao.selectOne(fbaDimensDoLambdaQueryWrapper);
        if (fbaDimensDo != null) {
            LambdaQueryWrapper<FbaShipPriceDo> fbaShipPriceDoLambdaQueryWrapper = new LambdaQueryWrapper<>();

            fbaShipPriceDoLambdaQueryWrapper.eq(FbaShipPriceDo::getDimensId, fbaDimensDo.getId()).eq(FbaShipPriceDo::getFbaStorageId, fbaStorageId).eq(FbaShipPriceDo::getVersion, shipPriceVersion).eq(FbaShipPriceDo::getActive, 1);

            FbaShipPriceDo fbaShipPriceDo = fbaShipPriceDao.selectOne(fbaShipPriceDoLambdaQueryWrapper);
            if (fbaShipPriceDo != null) {
                FbaShipPriceDo originShipPrice = getOriginShipPrice(fbaDimensDo.getId(), storageId, trackId, fbaStorageId);
                fbaShipPriceDo.setOriginalPrice((int) originShipPrice.getPrice());
//                return fbaShipPriceDo;
            } else {
                fbaShipPriceDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                fbaShipPriceDoLambdaQueryWrapper.eq(FbaShipPriceDo::getDimensId, fbaDimensDo.getId()).eq(FbaShipPriceDo::getFbaStorageId, fbaStorageId).eq(FbaShipPriceDo::getVersion, GlobalConstants.SHIP_PRICE_COMMON).eq(FbaShipPriceDo::getActive, 1);

                fbaShipPriceDo = fbaShipPriceDao.selectOne(fbaShipPriceDoLambdaQueryWrapper);
                FbaShipPriceDo originShipPrice = getOriginShipPrice(fbaDimensDo.getId(), storageId, trackId, fbaStorageId);
                if (originShipPrice != null) {
                    fbaShipPriceDo.setOriginalPrice((int) originShipPrice.getPrice());
                }
//                return fbaShipPriceDo;
            }
            res.setPriceDo(fbaShipPriceDo);
            if (fbaShipPriceDo == null) {
                //说明虽然匹配到了 尺寸 但是没有匹配到价格
                res.setType("priceReason");
                res.setReason("没有匹配到价格");
            }
            res.setSizeOrVol(fbaDimensDo.getSize());
        } else {
            //说明没有匹配到尺寸
            List<FbaDimensDo> dimensDoList = fbaDimensDao.selectList(new LambdaQueryWrapper<FbaDimensDo>().ge(FbaDimensDo::getSize, size).eq(FbaDimensDo::getType, sizeType).eq(FbaDimensDo::getStorageId, storageId).eq(FbaDimensDo::getTrackId, trackId).orderByAsc(FbaDimensDo::getSize));
            if (dimensDoList.size() == 0) {
                //说明 size 或者体积 不匹配
                if (sizeType == 1) {
                    res.setType("sizeReason");
                    //按三遍和
                    res.setReason("包裹最大尺寸：" + MathUtils.numberFormat(2, size) + "cm 超过支持的最大尺寸(" + et.getSize() + "cm)");
                } else {
                    res.setType("volReason");
                    res.setReason("所有包裹最大体积：" + MathUtils.numberFormat(2, size) + "m³ 超过支持的最大体积(" + et.getSize() + "m³)");
                }
                res.setSizeOrVol(et.getSize());
            } else {
                //说明 重量不匹配
                res.setType("weightReason");
                res.setReason("所有包裹最大重量：" + MathUtils.numberFormat(2, weight) + "kg 超过支持的最大重量(" + et.getWeight() + "kg)");
                res.setSizeOrVol(et.getWeight());
            }
        }
        return res;
    }

    private FbaShipPriceDo getShipPrice(double size, double weight, int sizeType, Long storageId, Long
            trackId, Long fbaStorageId, int shipPriceVersion) {
        return this.getShipPriceWithReason(size, weight, sizeType, storageId, trackId, fbaStorageId, shipPriceVersion).getPriceDo();
    }

    /**
     * 获取成本运输费用
     *
     * @param fbaDimensId
     * @param storageId
     * @param trackId
     * @param fbaStorageId
     * @return
     */
    private FbaShipPriceDo getOriginShipPrice(Long fbaDimensId, Long storageId, Long trackId, Long fbaStorageId) {
        LambdaQueryWrapper<FbaShipPriceDo> fbaShipPriceDoLambdaQueryWrapper = new LambdaQueryWrapper<>();

        fbaShipPriceDoLambdaQueryWrapper.eq(FbaShipPriceDo::getDimensId, fbaDimensId).eq(FbaShipPriceDo::getFbaStorageId, fbaStorageId).eq(FbaShipPriceDo::getVersion, 1).eq(FbaShipPriceDo::getActive, 1);

        FbaShipPriceDo fbaShipPriceDo = fbaShipPriceDao.selectOne(fbaShipPriceDoLambdaQueryWrapper);
        if (fbaShipPriceDo != null) {
            return fbaShipPriceDo;
        } else {
            fbaShipPriceDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            fbaShipPriceDoLambdaQueryWrapper.eq(FbaShipPriceDo::getDimensId, fbaDimensId).eq(FbaShipPriceDo::getFbaStorageId, fbaStorageId).eq(FbaShipPriceDo::getVersion, 1).eq(FbaShipPriceDo::getActive, 1);

            fbaShipPriceDo = fbaShipPriceDao.selectOne(fbaShipPriceDoLambdaQueryWrapper);
            return fbaShipPriceDo;
        }
    }

    @Override
    public void copyData() {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_type", 2);
        List<OrderOutputDo> orderOutputDoList = outputDao.selectList(wrapper);
        if (orderOutputDoList == null || orderOutputDoList.size() < 1) return;
        for (OrderOutputDo orderOutputDo : orderOutputDoList) {
            FbaOrderOutputDo fbaOrderOutputDo = new FbaOrderOutputDo();
            BeanUtils.copyProperties(orderOutputDo, fbaOrderOutputDo);
            dao.insert(fbaOrderOutputDo);
            wrapper = new QueryWrapper();
            wrapper.eq("order_output_id", orderOutputDo.getId());
            List<OrderOutputPackageDo> orderOutputPackageDos = outputPackageDao.selectList(wrapper);
            if (orderOutputPackageDos == null || orderOutputPackageDos.size() < 1) continue;
            for (OrderOutputPackageDo orderOutputPackageDo : orderOutputPackageDos) {
                FbaOrderOutputPackageDo fbaOrderOutputPackageDo = new FbaOrderOutputPackageDo();
                BeanUtils.copyProperties(orderOutputPackageDo, fbaOrderOutputPackageDo);
                fbaOrderOutputPackageDo.setFbaOrderOutputId(fbaOrderOutputDo.getId());
                packageDao.insert(fbaOrderOutputPackageDo);
                wrapper = new QueryWrapper();
                wrapper.eq("package_id", orderOutputPackageDo.getId());
                List<OrderOutputProductDo> orderOutputPackageDos1 = outputProductDao.selectList(wrapper);
                if (orderOutputPackageDos1 == null || orderOutputPackageDos1.size() < 1) continue;
                for (OrderOutputProductDo orderOutputPackageDo1 : orderOutputPackageDos1) {
                    FbaOrderOutputProductDo fbaOrderOutputPackageDo1 = new FbaOrderOutputProductDo();
                    BeanUtils.copyProperties(orderOutputPackageDo1, fbaOrderOutputPackageDo1);
                    fbaOrderOutputPackageDo1.setPackageId(fbaOrderOutputPackageDo.getId());
                    fbaOrderOutputPackageDo1.setOrderId(fbaOrderOutputDo.getId());
                    productDao.insert(fbaOrderOutputPackageDo1);
                }
            }
        }
    }


    /**
     * 批量拣货， 已打单直接出库预览
     *
     * @param req
     * @param userId
     * @param companyId
     * @return
     */
    @Override
    public List<BatchPickUpRes> batchPickUp(BatchPickUpReq req, Long userId, Long companyId) {
//        List<FbaOrderOutputDo> orderList = dao.selectList(new QueryWrapper<FbaOrderOutputDo>().in("id", req.getIds()));

        //将查出来的list 按仓库id、快递id、包裹性质（一单一件，一单多件）分组
//        Map<String, List<FbaOrderOutputDo>> mapList = orderList.stream().collect(Collectors.groupingBy(outputDo -> outputDo.getTrackId() + "-" + outputDo.getStorageId()));
        //遍历map取list
        List<BatchPickUpRes> pickUpList = new ArrayList<>();

        for (Long id : req.getIds()) {
            FbaOrderOutputDo et = dao.selectById(id);
            if (et == null) {
                continue;
            }
            Long trackId = et.getTrackId();
            Long storageId = et.getStorageId();

            BatchPickUpRes res = new BatchPickUpRes();
            List<PositionAndNumberDTO> positionAndNumberList = new ArrayList<>();

            StorageDo storageDo = storageDao.selectById(storageId);
            if (storageDo == null) {
                throw new BizException(SysConstant.Storage_NotExist);
            }
            res.setStorageName(storageDo.getStorageName());
            res.setStorageId(storageId);
            DicBusinessItemDo itemDo = dicBusinessItemDao.selectById(trackId);
            if (null != itemDo) {
                res.setTrackName(itemDo.getDicItemValue());
                res.setTrackId(trackId);
            }
            res.setOrderNumber(et.getFbaOrderOutputNumber());


            if (!DicBusinessItemConstant.fbaOrderCheckStatus.equals(et.getStatus()) && !DicBusinessItemConstant.fbaOrderPrintStatus.equals(et.getStatus()) && !DicBusinessItemConstant.fbaOrderAppointStorageStatus.equals(et.getStatus()) && !DicBusinessItemConstant.fbaOrderAppointCarStatus.equals(et.getStatus())) {
                throw new BizException(SysConstant.FbaOrder_Pickup_Status_Error1, et.getFbaOrderOutputNumber());
            }
            if (et.getPickUpId() != null) {
                StockPickUpDo pickUpDo = stockPickUpDao.selectById(et.getPickUpId());
                if (pickUpDo != null && pickUpDo.getStatus() == 1) {
                    //已拣货 报错
                    throw new BizException(SysConstant.FbaOrder_Pickup_Status_Error2, et.getFbaOrderOutputNumber(), pickUpDo.getPickUpNumber());
                }
            }
            Map<String, Integer> countMap = new HashMap<>();
            LambdaQueryWrapper<FbaOrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FbaOrderOutputPackageDo::getFbaOrderOutputId, et.getId());
            List<FbaOrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
            for (FbaOrderOutputPackageDo packageDo : packageDoList) {
                List<FbaOrderOutputProductDo> productList = productDao.selectList(new QueryWrapper<FbaOrderOutputProductDo>().eq("package_id", packageDo.getId()));
                for (FbaOrderOutputProductDo pt : productList) {
                    countMap.merge(pt.getProductId() + "-" + et.getStorageId() + "-" + et.getCompanyId(), pt.getCount() * packageDo.getCount(), Integer::sum);
                }
            }
            for (String value : countMap.keySet()) {
                Long productId = Long.parseLong(value.split("-")[0]);
                ProductInfoDo productInfoDo = productInfoDao.selectById(productId);
                if (productInfoDo == null) {
                    throw new BizException(SysConstant.Product_NotExist);
                }
                Map<String, String> map = new HashMap<>();
                map.put("productId", productId + "");
                map.put("storageId", value.split("-")[1]);
                map.put("companyId", value.split("-")[2]);
                //倒序获取库位货存 可做到先进先出
                List<PickupStockRackDto> stockRackList = productStockRackDao.getStockRackBySort(map);
                int finalGoodQuantity = countMap.get(value);
                this.fbaSortStockRackList(stockRackList, finalGoodQuantity);

                //先把 countTotalMap 里面的数据 减去
                int goodQuantity = countMap.get(value);
                if (stockRackList.size() <= 0) {
                    ShopDo shopDo = shopDao.selectById(et.getShopId());
                    throw new BizException(SysConstant.Order_Pickup_Error_Stock, et.getFbaOrderOutputNumber(), (shopDo != null ? shopDo.getShopName() : "未匹配"), storageDo.getStorageName(), productInfoDo.getCommoditySku());
                }
                for (PickupStockRackDto st : stockRackList) {
                    if (st.getGoodQuantity() <= 0) {
                        continue;
                    }
                    goodQuantity = stockPickUpService.getPositionAndNumberDTO(positionAndNumberList, st, productInfoDo, storageDo, goodQuantity, et.getId());
                    if (goodQuantity <= 0) {
                        break;
                    }
                }
                if (goodQuantity > 0) {
                    ShopDo shopDo = shopDao.selectById(et.getShopId());
                    throw new BizException(SysConstant.Order_Pickup_Error_Stock, et.getFbaOrderOutputNumber(), (shopDo != null ? shopDo.getShopName() : "未匹配"), storageDo.getStorageName(), productInfoDo.getCommoditySku());
                }
            }
            res.setPositionAndNumberList(positionAndNumberList);
            pickUpList.add(res);
        }

        if (pickUpList.size() > 0) {
            for (BatchPickUpRes batchPickUpRes : pickUpList) {
                List<PositionAndNumberDTO> list = stockPickUpService.getShowList(batchPickUpRes.getPositionAndNumberList());
                batchPickUpRes.setShowList(list);
            }
        }
        return pickUpList;
    }

    @Override
    public void fbaSortStockRackList(List<PickupStockRackDto> stockRackList, int finalGoodQuantity) {
        //按库位分好，处理 有些虽然库存很多。但是分批次录入的，导致分成了很多条记录
        Map<Long, List<PickupStockRackDto>> stockRackMapList = stockRackList.stream().filter(i -> i.getPositionId() != null).collect(Collectors.groupingBy(PickupStockRackDto::getPositionId));

        List<PickupStockRackDto> defaultRackList = stockRackList.stream().filter(i -> i.getPositionId() == null).collect(Collectors.toList());
        int defaultGoodQuantity = defaultRackList.stream().mapToInt(PickupStockRackDto::getGoodQuantity).sum();
        List<Long> positionIdList = new ArrayList<>(stockRackMapList.keySet());
        if (defaultRackList.size() > 0) {
            positionIdList.add(null);
        }
        //将库位id排序
        //fba 特殊要求 1层最后，在默认库位 ,然后 2345..层优先,然后 能全部出完得库位优先


        positionIdList.sort(new Comparator<Long>() {
            //fba 优先fba转运区
            @Override
            public int compare(Long p1, Long p2) {
                PickupStockRackDto o1 = p1 == null ? defaultRackList.get(0) : stockRackMapList.get(p1).get(0);
                PickupStockRackDto o2 = p2 == null ? defaultRackList.get(0) : stockRackMapList.get(p2).get(0);
                int goodQuantity1 = p1 == null ? defaultGoodQuantity : stockRackMapList.get(p1).stream().mapToInt(PickupStockRackDto::getGoodQuantity).sum();
                int goodQuantity2 = p2 == null ? defaultGoodQuantity : stockRackMapList.get(p2).stream().mapToInt(PickupStockRackDto::getGoodQuantity).sum();

                if (o1.getFba() == null && o2.getFba() == null) {
                    return 0;
                } else if (o1.getFba() == null && o2.getFba() != null && o2.getFba() == 1) {
                    //o1默认库位 o2 fba转运区
                    return 1;
                } else if (o2.getFba() == null && o1.getFba() != null && o1.getFba() == 1) {
                    //o2默认库位 o1 fba转运区
                    return -1;
                } else if (o1.getFba() != null && o2.getFba() != null && o1.getFba() == 0 && o2.getFba() == 1) {
                    //o1是非fba转运区 o2是fba转运区 o1排在后面
                    return 1;
                } else if (o2.getFba() != null && o1.getFba() != null && o1.getFba() == 1 && o2.getFba() == 0) {
                    //o2是非fba转运区 o1是fba转运区 o2排在后面
                    return -1;
                } else {
                    //先判断默认库位的情况 默认库位在 1层前 在 23层之后
                    if (o1.getRackId() == null && o2.getRackId() == null) {
                        return 0;
                    } else if (o1.getRackId() == null) {
                        // o1 是默认库位
                        if (o2.getTierNumber() == null || o2.getTierNumber() == 1) {
                            //o2 是 第一层
                            return -1;
                        } else {
                            // o2 是 23层
                            return 1;
                        }
                    } else if (o2.getRackId() == null) {
                        if (o1.getTierNumber() == null || o1.getTierNumber() == 1) {
                            //o1 是 第一层
                            return 1;
                        } else {
                            // o1 是 23层
                            return -1;
                        }
                    } else {
                        if ((o1.getTierNumber() == null || o1.getTierNumber() == 1) && (o2.getTierNumber() == null || o2.getTierNumber() == 1)) {
                            //o1 o2 都是一层 在比较 库位数量能否全部出完
                            if (goodQuantity1 >= finalGoodQuantity && goodQuantity2 < finalGoodQuantity) {
                                //o1 的数量满足 o2的数量不满足
                                return -1;
                            } else if (goodQuantity2 >= finalGoodQuantity && goodQuantity1 < finalGoodQuantity) {
                                return 1;
                            } else {
                                //o1 o2 数量都满足 再去比较层数
                                if (!o1.getGridNumber().equals(o2.getGridNumber())) {
                                    return o1.getGridNumber() - o2.getGridNumber();
                                } else {
                                    return o1.getShelfNumber() - o2.getShelfNumber();
                                }
                            }
                        } else if ((o1.getTierNumber() == null || o1.getTierNumber() == 1) && !(o2.getTierNumber() == null || o2.getTierNumber() == 1)) {
                            //o1一层 o2其他
                            return 1;
                        } else if (!(o1.getTierNumber() == null || o1.getTierNumber() == 1) && (o2.getTierNumber() == null || o2.getTierNumber() == 1)) {
                            //o2一层 o1其他
                            return -1;
                        } else if (o1.getTierNumber() == null && o2.getTierNumber() != null) {
                            return 1;
                        } else if (o1.getTierNumber() != null && o2.getTierNumber() == null) {
                            return -1;
                        } else {
                            //o1 o2 都是 其他层 优先看谁能全部出完。再按层数
                            if (goodQuantity1 >= finalGoodQuantity && goodQuantity2 < finalGoodQuantity) {
                                //o1 的数量满足 o2的数量不满足
                                return -1;
                            } else if (goodQuantity2 >= finalGoodQuantity && goodQuantity1 < finalGoodQuantity) {
                                return 1;
                            } else {
                                //o1 o2 数量都满足 再去比较层数
                                if (o1.getTierNumber() == null && o2.getTierNumber() != null) {
                                    return 1;
                                } else if (o1.getTierNumber() != null && o2.getTierNumber() == null) {
                                    return -1;
                                } else if (o1.getTierNumber() == null && o2.getTierNumber() == null) {
                                    return 0;
                                } else if (!o1.getTierNumber().equals(o2.getTierNumber())) {
                                    return o1.getTierNumber() - o2.getTierNumber();
                                } else {
                                    if (!o1.getGridNumber().equals(o2.getGridNumber())) {
                                        return o1.getGridNumber() - o2.getGridNumber();
                                    } else {
                                        return o1.getShelfNumber() - o2.getShelfNumber();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        });

        Map<Long, Integer> positionSortMap = new HashMap<>();
        for (int i = 0; i < positionIdList.size(); i++) {
            positionSortMap.put(positionIdList.get(i), i);
        }

        stockRackList.sort(new Comparator<PickupStockRackDto>() {
            @Override
            public int compare(PickupStockRackDto o1, PickupStockRackDto o2) {
//                        if (o1.getPositionId() == null && o2.getPositionId() != null) {
//                            return 1;
//                        } else if (o1.getPositionId() != null && o2.getPositionId() == null) {
//                            return -1;
//                        } else if (o1.getPositionId() == null && o2.getPositionId() == null) {
//                            return 0;
//                        } else {
                //根据库位id 排序
                return positionSortMap.get(o1.getPositionId()) - positionSortMap.get(o2.getPositionId());
//                        }
            }
        });
    }


    /**
     * 已打单/已约仓/已约车
     *
     * @param positionAndNumberList
     * @param orderOutputDo
     * @param userId
     */
    public void sendWhenOutWaitSendOut(List<PositionAndNumberDTO> positionAndNumberList, FbaOrderOutputDo
            orderOutputDo, Long oldStatus, Long userId, boolean omsFlag) {
        //orderOutputDo 的 status 已经改成了 已发货
        String statusName = oldStatus.equals(DicBusinessItemConstant.fbaOrderPrintStatus) ? "已打单" : (oldStatus.equals(DicBusinessItemConstant.fbaOrderAppointStorageStatus) ? "已约仓" : (oldStatus.equals(DicBusinessItemConstant.fbaOrderAppointCarStatus) ? "已约车" : ""));
//        if (StringUtils.isBlank(statusName)) {
//            throw new BizException("只有已打单/已约仓/已约车 才可以发货");
//        }

        //已打单状态 直接发货, 不需要锁定库位，随机分配库位，获取方法调用朱加乐得接口,直接去扣库存
        for (PositionAndNumberDTO positionAndNumberDTO : positionAndNumberList) {
            ProductStockRackDo stockRackDo = productStockRackDao.selectById(positionAndNumberDTO.getStockRackId());
            if (stockRackDo == null) {
                throw new BizException(SysConstant.Order_StockRack_NotExist);
            }
            if (stockRackDo.getGoodQuantity() < positionAndNumberDTO.getNumber()) {
                throw new BizException(SysConstant.Order_StockRack_NotEnough);
            }
            stockRackDo.setGoodQuantity(stockRackDo.getGoodQuantity() - positionAndNumberDTO.getNumber());
            productStockRackDao.updateById(stockRackDo);
            //插入出库记录,并操作旧表库存
            productOutService.dealWithStock(stockRackDo.getStockId(), positionAndNumberDTO.getProductId(), orderOutputDo.getStorageId(), orderOutputDo.getShopId(), orderOutputDo.getCompanyId(), userId, positionAndNumberDTO.getNumber(), orderOutputDo.getFbaOrderOutputNumber(), orderOutputDo.getFbaOrderOutputNumber(), "fbaOutput", "fbaOutput", omsFlag);
            if (stockRackDo.getGoodQuantity() == 0 && stockRackDo.getBadQuantity() == 0 && stockRackDo.getGoodLockQuantity() == 0 && stockRackDo.getBadLockQuantity() == 0) {
                productStockRackDao.deleteById(stockRackDo);
                int count = productStockRackDao.selectCount(new LambdaQueryWrapper<ProductStockRackDo>().eq(ProductStockRackDo::getStockId, stockRackDo.getStockId()).orderByDesc(ProductStockRackDo::getRackId));
                if (count == 0) {
                    productStockDao.deleteById(stockRackDo.getStockId());
                }
            }

            //并插入流水 库存流水新
            productStockFlowingService.insertFlowing(StaticDict.Product_Flowing_Type.FbaOutput.getValue(), orderOutputDo.getFbaOrderOutputNumber(), orderOutputDo.getShopId(), positionAndNumberDTO.getProductId(), orderOutputDo.getStorageId(), -positionAndNumberDTO.getNumber(), 0, 0, positionAndNumberDTO.getRackId(), orderOutputDo.getCompanyId(), userId, "FBA出库单 " + statusName + " 直接发货");

            //此记录单纯给 fba出库单回滚用
            productStockFlowingService.insertFlowing(StaticDict.Product_Flowing_Type.FbaSend.getValue(), orderOutputDo.getFbaOrderOutputNumber(), orderOutputDo.getShopId(), positionAndNumberDTO.getProductId(), orderOutputDo.getStorageId(), -positionAndNumberDTO.getNumber(), 0, 0, positionAndNumberDTO.getRackId(), orderOutputDo.getCompanyId(), userId, "fba出库单:" + orderOutputDo.getFbaOrderOutputNumber() + "发货记录");
        }
    }

    @Override
    public List<FbaOrderFileResponse> exportOrderFbaFile(Long id, int type) {
        FbaOrderOutputDo fbaOrderOutputDo = dao.selectById(id);
        if (fbaOrderOutputDo == null) throw new BizException(SysConstant.Order_NotExist);
        List<FbaOrderFileResponse> responseList = new ArrayList<>();
        String filePath = fileService.getFilePath(fbaOrderOutputDo.getFileId());
        if (1 == type && StringUtils.isNotBlank(filePath)) {
            FileDo fileDo = fileService.getById(fbaOrderOutputDo.getFileId());
            responseList.add(new FbaOrderFileResponse(fbaOrderOutputDo.getId(), fbaOrderOutputDo.getFileId(), 1, filePath, "", fileDo.getFileSuffix()));
        }
        String productFilePath = fileService.getFilePath(fbaOrderOutputDo.getProductFileId());
        if (2 == type && StringUtils.isNotBlank(productFilePath)) {
            FileDo fileDo = fileService.getById(fbaOrderOutputDo.getProductFileId());
            responseList.add(new FbaOrderFileResponse(fbaOrderOutputDo.getId(), fbaOrderOutputDo.getProductFileId(), 2, productFilePath, "", fileDo.getFileSuffix()));
        }
        String otherFilePath = fileService.getFilePath(fbaOrderOutputDo.getOtherFileId());
        if (3 == type && StringUtils.isNotBlank(productFilePath)) {
            FileDo fileDo = fileService.getById(fbaOrderOutputDo.getOtherFileId());
            responseList.add(new FbaOrderFileResponse(fbaOrderOutputDo.getId(), fbaOrderOutputDo.getOtherFileId(), 3, otherFilePath, "", fileDo.getFileSuffix()));
        }
        return responseList;
    }
}
